mirror of
https://github.com/bevyengine/bevy
synced 2024-11-10 07:04:33 +00:00
render: add RenderPipeline and begin moving logic there
This commit is contained in:
parent
97edaa7343
commit
f799d3ac93
17 changed files with 229 additions and 230 deletions
|
@ -1,8 +1,8 @@
|
|||
use crate::{light::Light, material::StandardMaterial};
|
||||
use bevy_asset::Handle;
|
||||
use bevy_derive::EntityArchetype;
|
||||
use bevy_render::{mesh::Mesh, draw::{RenderPipelines, Draw}};
|
||||
use bevy_transform::prelude::{Transform, Rotation, Scale, Translation};
|
||||
use bevy_render::{draw::Draw, mesh::Mesh, pipeline::RenderPipelines};
|
||||
use bevy_transform::prelude::{Rotation, Scale, Transform, Translation};
|
||||
|
||||
#[derive(EntityArchetype, Default)]
|
||||
pub struct MeshEntity {
|
||||
|
|
|
@ -58,26 +58,6 @@ impl Default for Draw {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Properties)]
|
||||
pub struct RenderPipelines {
|
||||
pub pipelines: Vec<Handle<PipelineDescriptor>>,
|
||||
// TODO: make these pipeline specific
|
||||
#[property(ignore)]
|
||||
pub render_resource_bindings: RenderResourceBindings,
|
||||
#[property(ignore)]
|
||||
pub compiled_pipelines: Vec<Handle<PipelineDescriptor>>,
|
||||
}
|
||||
|
||||
impl Default for RenderPipelines {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
render_resource_bindings: Default::default(),
|
||||
compiled_pipelines: Default::default(),
|
||||
pipelines: vec![Handle::default()],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Draw {
|
||||
pub fn get_context<'a>(
|
||||
&'a mut self,
|
||||
|
@ -201,54 +181,6 @@ pub trait Drawable {
|
|||
fn draw(&mut self, draw: &mut DrawContext) -> Result<(), DrawError>;
|
||||
}
|
||||
|
||||
impl Drawable for RenderPipelines {
|
||||
fn draw(&mut self, draw: &mut DrawContext) -> Result<(), DrawError> {
|
||||
for pipeline_handle in self.compiled_pipelines.iter() {
|
||||
let pipeline = draw.pipelines.get(pipeline_handle).unwrap();
|
||||
let layout = pipeline.get_layout().unwrap();
|
||||
draw.set_pipeline(*pipeline_handle)?;
|
||||
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_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_descriptor, global_bind_group);
|
||||
}
|
||||
}
|
||||
let mut indices = 0..0;
|
||||
for (slot, vertex_buffer_descriptor) in
|
||||
layout.vertex_buffer_descriptors.iter().enumerate()
|
||||
{
|
||||
if let Some((vertex_buffer, index_buffer)) = self
|
||||
.render_resource_bindings
|
||||
.get_vertex_buffer(&vertex_buffer_descriptor.name)
|
||||
{
|
||||
draw.set_vertex_buffer(slot as u32, vertex_buffer, 0);
|
||||
if let Some(index_buffer) = index_buffer {
|
||||
if let Some(buffer_info) =
|
||||
draw.render_resource_context.get_buffer_info(index_buffer)
|
||||
{
|
||||
indices = 0..(buffer_info.size / 2) as u32;
|
||||
} else {
|
||||
panic!("expected buffer type");
|
||||
}
|
||||
draw.set_index_buffer(index_buffer, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
draw.draw_indexed(indices, 0, 0..1);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
pub fn draw_system<T: Drawable + Component>(
|
||||
pipelines: Res<Assets<PipelineDescriptor>>,
|
||||
render_resource_bindings: Res<RenderResourceBindings>,
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use crate::{
|
||||
base_render_graph, mesh::Mesh, Camera, OrthographicProjection, PerspectiveProjection,
|
||||
RenderPipelines, WindowOrigin, draw::Draw,
|
||||
WindowOrigin, draw::Draw, pipeline::RenderPipelines,
|
||||
};
|
||||
use bevy_asset::Handle;
|
||||
use bevy_derive::EntityArchetype;
|
||||
|
|
|
@ -35,10 +35,10 @@ use base_render_graph::{BaseRenderGraphBuilder, BaseRenderGraphConfig};
|
|||
use bevy_app::{AppBuilder, AppPlugin};
|
||||
use bevy_asset::AddAsset;
|
||||
use bevy_type_registry::RegisterType;
|
||||
use draw::{clear_draw_system, draw_system, Draw, RenderPipelines};
|
||||
use draw::{clear_draw_system, draw_system, Draw};
|
||||
use legion::prelude::IntoSystem;
|
||||
use mesh::mesh_resource_provider_system;
|
||||
use pipeline::compile_pipelines_system;
|
||||
use pipeline::{RenderPipelines, compile_pipelines_system};
|
||||
use render_graph::{system::render_graph_schedule_executor_system, RenderGraph};
|
||||
use render_resource::bind_groups_system;
|
||||
use std::ops::Range;
|
||||
|
|
|
@ -408,16 +408,17 @@ pub fn mesh_resource_provider_system(resources: &mut Resources) -> Box<dyn Sched
|
|||
// TODO: remove this once batches are pipeline specific and deprecate assigned_meshes draw target
|
||||
for (handle, mut render_pipelines) in query.iter_mut(world) {
|
||||
if let Some(mesh) = meshes.get(&handle) {
|
||||
render_pipelines
|
||||
.render_resource_bindings
|
||||
.pipeline_specialization
|
||||
.primitive_topology = mesh.primitive_topology;
|
||||
for render_pipeline in render_pipelines.pipelines.iter_mut() {
|
||||
render_pipeline
|
||||
.specialization
|
||||
.primitive_topology = mesh.primitive_topology;
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(RenderResourceId::Buffer(vertex_buffer)) =
|
||||
render_resource_context.get_asset_resource(*handle, VERTEX_BUFFER_ASSET_INDEX)
|
||||
{
|
||||
render_pipelines.render_resource_bindings.set_vertex_buffer(
|
||||
render_pipelines.bindings.set_vertex_buffer(
|
||||
"Vertex",
|
||||
vertex_buffer,
|
||||
render_resource_context
|
||||
|
|
|
@ -5,6 +5,7 @@ mod pipeline_compiler;
|
|||
mod pipeline_layout;
|
||||
pub mod state_descriptors;
|
||||
mod vertex_buffer_descriptor;
|
||||
mod render_pipelines;
|
||||
mod vertex_format;
|
||||
|
||||
pub use bind_group::*;
|
||||
|
@ -12,5 +13,6 @@ pub use binding::*;
|
|||
pub use pipeline::*;
|
||||
pub use pipeline_compiler::*;
|
||||
pub use pipeline_layout::*;
|
||||
pub use render_pipelines::*;
|
||||
pub use vertex_buffer_descriptor::*;
|
||||
pub use vertex_format::*;
|
|
@ -1,8 +1,10 @@
|
|||
use super::{state_descriptors::PrimitiveTopology, PipelineDescriptor, VertexBufferDescriptors};
|
||||
use super::{
|
||||
state_descriptors::PrimitiveTopology, PipelineDescriptor, RenderPipeline, RenderPipelines,
|
||||
VertexBufferDescriptors,
|
||||
};
|
||||
use crate::{
|
||||
draw::RenderPipelines,
|
||||
renderer::RenderResourceContext,
|
||||
shader::{Shader, ShaderSource},
|
||||
shader::{Shader, ShaderSource}, render_resource::RenderResourceBindings,
|
||||
};
|
||||
use bevy_asset::{Assets, Handle};
|
||||
use std::collections::{HashMap, HashSet};
|
||||
|
@ -25,7 +27,7 @@ pub struct ShaderSpecialization {
|
|||
pub struct PipelineCompiler {
|
||||
pub shader_source_to_compiled:
|
||||
HashMap<Handle<Shader>, Vec<(ShaderSpecialization, Handle<Shader>)>>,
|
||||
pub pipeline_source_to_compiled: HashMap<
|
||||
pub specialized_pipelines: HashMap<
|
||||
Handle<PipelineDescriptor>,
|
||||
Vec<(PipelineSpecialization, Handle<PipelineDescriptor>)>,
|
||||
>,
|
||||
|
@ -78,17 +80,15 @@ impl PipelineCompiler {
|
|||
vertex_buffer_descriptors: &VertexBufferDescriptors,
|
||||
shaders: &mut Assets<Shader>,
|
||||
pipeline_descriptor: &PipelineDescriptor,
|
||||
render_pipelines: &RenderPipelines,
|
||||
render_pipeline: &RenderPipeline,
|
||||
render_resource_bindings: &RenderResourceBindings,
|
||||
) -> PipelineDescriptor {
|
||||
let mut compiled_pipeline_descriptor = pipeline_descriptor.clone();
|
||||
|
||||
compiled_pipeline_descriptor.shader_stages.vertex = self.compile_shader(
|
||||
shaders,
|
||||
&pipeline_descriptor.shader_stages.vertex,
|
||||
&render_pipelines
|
||||
.render_resource_bindings
|
||||
.pipeline_specialization
|
||||
.shader_specialization,
|
||||
&render_pipeline.specialization.shader_specialization,
|
||||
);
|
||||
compiled_pipeline_descriptor.shader_stages.fragment = pipeline_descriptor
|
||||
.shader_stages
|
||||
|
@ -98,10 +98,7 @@ impl PipelineCompiler {
|
|||
self.compile_shader(
|
||||
shaders,
|
||||
fragment,
|
||||
&render_pipelines
|
||||
.render_resource_bindings
|
||||
.pipeline_specialization
|
||||
.shader_specialization,
|
||||
&render_pipeline.specialization.shader_specialization,
|
||||
)
|
||||
});
|
||||
|
||||
|
@ -109,13 +106,11 @@ impl PipelineCompiler {
|
|||
shaders,
|
||||
true,
|
||||
Some(vertex_buffer_descriptors),
|
||||
Some(&render_pipelines.render_resource_bindings),
|
||||
Some(render_resource_bindings),
|
||||
);
|
||||
|
||||
compiled_pipeline_descriptor.primitive_topology = render_pipelines
|
||||
.render_resource_bindings
|
||||
.pipeline_specialization
|
||||
.primitive_topology;
|
||||
compiled_pipeline_descriptor.primitive_topology =
|
||||
render_pipeline.specialization.primitive_topology;
|
||||
compiled_pipeline_descriptor
|
||||
}
|
||||
|
||||
|
@ -127,31 +122,29 @@ impl PipelineCompiler {
|
|||
render_pipelines: &mut RenderPipelines,
|
||||
render_resource_context: &dyn RenderResourceContext,
|
||||
) {
|
||||
for (i, pipeline_handle) in render_pipelines.pipelines.iter().enumerate() {
|
||||
if let None = self.pipeline_source_to_compiled.get(pipeline_handle) {
|
||||
self.pipeline_source_to_compiled
|
||||
.insert(*pipeline_handle, Vec::new());
|
||||
for render_pipeline in render_pipelines.pipelines.iter_mut() {
|
||||
let source_pipeline = render_pipeline.pipeline;
|
||||
if let None = self.specialized_pipelines.get(&source_pipeline) {
|
||||
self.specialized_pipelines
|
||||
.insert(source_pipeline, Vec::new());
|
||||
}
|
||||
|
||||
let compiled_pipeline_handle = if let Some((_shader_defs, compiled_pipeline_handle)) =
|
||||
self.pipeline_source_to_compiled
|
||||
.get_mut(pipeline_handle)
|
||||
self.specialized_pipelines
|
||||
.get_mut(&source_pipeline)
|
||||
.unwrap()
|
||||
.iter()
|
||||
.find(|(pipeline_specialization, _compiled_pipeline_handle)| {
|
||||
*pipeline_specialization
|
||||
== render_pipelines
|
||||
.render_resource_bindings
|
||||
.pipeline_specialization
|
||||
*pipeline_specialization == render_pipeline.specialization
|
||||
}) {
|
||||
*compiled_pipeline_handle
|
||||
} else {
|
||||
let pipeline_descriptor = pipelines.get(pipeline_handle).unwrap();
|
||||
let pipeline_descriptor = pipelines.get(&source_pipeline).unwrap();
|
||||
let compiled_pipeline_descriptor = self.compile_pipeline(
|
||||
vertex_buffer_descriptors,
|
||||
shaders,
|
||||
pipeline_descriptor,
|
||||
render_pipelines,
|
||||
render_pipeline,
|
||||
&render_pipelines.bindings,
|
||||
);
|
||||
let compiled_pipeline_handle = pipelines.add(compiled_pipeline_descriptor);
|
||||
render_resource_context.create_render_pipeline(
|
||||
|
@ -161,26 +154,17 @@ impl PipelineCompiler {
|
|||
);
|
||||
|
||||
let compiled_pipelines = self
|
||||
.pipeline_source_to_compiled
|
||||
.get_mut(pipeline_handle)
|
||||
.specialized_pipelines
|
||||
.get_mut(&source_pipeline)
|
||||
.unwrap();
|
||||
compiled_pipelines.push((
|
||||
render_pipelines
|
||||
.render_resource_bindings
|
||||
.pipeline_specialization
|
||||
.clone(),
|
||||
render_pipeline.specialization.clone(),
|
||||
compiled_pipeline_handle,
|
||||
));
|
||||
compiled_pipeline_handle
|
||||
};
|
||||
|
||||
if i == render_pipelines.compiled_pipelines.len() {
|
||||
render_pipelines
|
||||
.compiled_pipelines
|
||||
.push(compiled_pipeline_handle);
|
||||
} else {
|
||||
render_pipelines.compiled_pipelines[i] = compiled_pipeline_handle;
|
||||
}
|
||||
render_pipeline.specialized_pipeline = Some(compiled_pipeline_handle);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -188,7 +172,7 @@ impl PipelineCompiler {
|
|||
&self,
|
||||
pipeline_handle: Handle<PipelineDescriptor>,
|
||||
) -> Option<impl Iterator<Item = &Handle<PipelineDescriptor>>> {
|
||||
if let Some(compiled_pipelines) = self.pipeline_source_to_compiled.get(&pipeline_handle) {
|
||||
if let Some(compiled_pipelines) = self.specialized_pipelines.get(&pipeline_handle) {
|
||||
Some(compiled_pipelines.iter().map(|(_, handle)| handle))
|
||||
} else {
|
||||
None
|
||||
|
@ -196,7 +180,7 @@ impl PipelineCompiler {
|
|||
}
|
||||
|
||||
pub fn iter_all_compiled_pipelines(&self) -> impl Iterator<Item = &Handle<PipelineDescriptor>> {
|
||||
self.pipeline_source_to_compiled
|
||||
self.specialized_pipelines
|
||||
.values()
|
||||
.map(|compiled_pipelines| {
|
||||
compiled_pipelines
|
||||
|
@ -230,11 +214,12 @@ pub fn compile_pipelines_system(
|
|||
);
|
||||
|
||||
// reset shader_defs so they can be changed next frame
|
||||
render_pipelines
|
||||
.render_resource_bindings
|
||||
.pipeline_specialization
|
||||
.shader_specialization
|
||||
.shader_defs
|
||||
.clear();
|
||||
for render_pipeline in render_pipelines.pipelines.iter_mut() {
|
||||
render_pipeline
|
||||
.specialization
|
||||
.shader_specialization
|
||||
.shader_defs
|
||||
.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
107
crates/bevy_render/src/pipeline/render_pipelines.rs
Normal file
107
crates/bevy_render/src/pipeline/render_pipelines.rs
Normal file
|
@ -0,0 +1,107 @@
|
|||
use super::{PipelineDescriptor, PipelineSpecialization};
|
||||
use crate::{
|
||||
draw::{DrawContext, DrawError, Drawable},
|
||||
render_resource::RenderResourceBindings,
|
||||
};
|
||||
use bevy_asset::Handle;
|
||||
use bevy_property::Properties;
|
||||
#[derive(Properties, Default, Clone)]
|
||||
pub struct RenderPipeline {
|
||||
pub pipeline: Handle<PipelineDescriptor>,
|
||||
#[property(ignore)]
|
||||
pub specialized_pipeline: Option<Handle<PipelineDescriptor>>,
|
||||
#[property(ignore)]
|
||||
pub specialization: PipelineSpecialization,
|
||||
}
|
||||
|
||||
impl RenderPipeline {
|
||||
pub fn new(pipeline: Handle<PipelineDescriptor>) -> Self {
|
||||
RenderPipeline {
|
||||
pipeline,
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Properties)]
|
||||
pub struct RenderPipelines {
|
||||
pub pipelines: Vec<RenderPipeline>,
|
||||
#[property(ignore)]
|
||||
pub bindings: RenderResourceBindings,
|
||||
}
|
||||
|
||||
impl RenderPipelines {
|
||||
pub fn from_handles<'a, T: IntoIterator<Item = &'a Handle<PipelineDescriptor>>>(
|
||||
handles: T,
|
||||
) -> Self {
|
||||
RenderPipelines {
|
||||
pipelines: handles
|
||||
.into_iter()
|
||||
.map(|pipeline| RenderPipeline::new(*pipeline))
|
||||
.collect::<Vec<RenderPipeline>>(),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for RenderPipelines {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
bindings: Default::default(),
|
||||
pipelines: vec![RenderPipeline::default()],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Drawable for RenderPipelines {
|
||||
fn draw(&mut self, draw: &mut DrawContext) -> Result<(), DrawError> {
|
||||
for render_pipeline in self.pipelines.iter() {
|
||||
let specialized_handle = if let Some(handle) = render_pipeline.specialized_pipeline {
|
||||
handle
|
||||
} else {
|
||||
continue;
|
||||
};
|
||||
let pipeline = draw.pipelines.get(&specialized_handle).unwrap();
|
||||
let layout = pipeline.get_layout().unwrap();
|
||||
draw.set_pipeline(specialized_handle)?;
|
||||
for bind_group_descriptor in layout.bind_groups.iter() {
|
||||
if let Some(local_bind_group) = self
|
||||
.bindings
|
||||
.get_descriptor_bind_group(bind_group_descriptor.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_descriptor, global_bind_group);
|
||||
}
|
||||
}
|
||||
let mut indices = 0..0;
|
||||
for (slot, vertex_buffer_descriptor) in
|
||||
layout.vertex_buffer_descriptors.iter().enumerate()
|
||||
{
|
||||
if let Some((vertex_buffer, index_buffer)) = self
|
||||
.bindings
|
||||
.get_vertex_buffer(&vertex_buffer_descriptor.name)
|
||||
{
|
||||
draw.set_vertex_buffer(slot as u32, vertex_buffer, 0);
|
||||
if let Some(index_buffer) = index_buffer {
|
||||
if let Some(buffer_info) =
|
||||
draw.render_resource_context.get_buffer_info(index_buffer)
|
||||
{
|
||||
indices = 0..(buffer_info.size / 2) as u32;
|
||||
} else {
|
||||
panic!("expected buffer type");
|
||||
}
|
||||
draw.set_index_buffer(index_buffer, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
draw.draw_indexed(indices, 0, 0..1);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
use crate::{
|
||||
draw::{Draw, RenderPipelines},
|
||||
draw::Draw,
|
||||
pipeline::RenderPipelines,
|
||||
render_graph::{CommandQueue, Node, ResourceSlots, SystemNode},
|
||||
render_resource::{
|
||||
self, BufferInfo, BufferUsage, RenderResourceBinding, RenderResourceBindings,
|
||||
|
@ -373,8 +374,7 @@ where
|
|||
(move |world: &mut SubWorld,
|
||||
render_resource_context: Res<Box<dyn RenderResourceContext>>,
|
||||
query: &mut Query<(Read<T>, Read<Draw>, Write<RenderPipelines>)>| {
|
||||
|
||||
let render_resource_context = &** render_resource_context;
|
||||
let render_resource_context = &**render_resource_context;
|
||||
uniform_buffer_arrays.reset_changed_item_counts();
|
||||
// update uniforms info
|
||||
for (uniforms, draw, _render_pipelines) in query.iter_mut(world) {
|
||||
|
@ -396,7 +396,7 @@ where
|
|||
setup_uniform_texture_resources::<T>(
|
||||
&uniforms,
|
||||
render_resource_context,
|
||||
&mut render_pipelines.render_resource_bindings,
|
||||
&mut render_pipelines.bindings,
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -411,7 +411,7 @@ where
|
|||
&uniforms,
|
||||
dynamic_uniforms,
|
||||
render_resource_context,
|
||||
&mut render_pipelines.render_resource_bindings,
|
||||
&mut render_pipelines.bindings,
|
||||
&mut staging_buffer,
|
||||
);
|
||||
}
|
||||
|
@ -432,7 +432,7 @@ where
|
|||
&uniforms,
|
||||
dynamic_uniforms,
|
||||
render_resource_context,
|
||||
&mut render_pipelines.render_resource_bindings,
|
||||
&mut render_pipelines.bindings,
|
||||
&mut staging_buffer,
|
||||
);
|
||||
}
|
||||
|
@ -598,9 +598,7 @@ where
|
|||
|
||||
for (asset_handle, _draw, mut render_pipelines) in query.iter_mut(world) {
|
||||
if let Some(asset_bindings) = asset_render_resource_bindings.get(&asset_handle) {
|
||||
render_pipelines
|
||||
.render_resource_bindings
|
||||
.extend(asset_bindings);
|
||||
render_pipelines.bindings.extend(asset_bindings);
|
||||
}
|
||||
}
|
||||
})
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use super::{BufferId, RenderResourceId, BindGroup, BindGroupId, SamplerId, TextureId};
|
||||
use crate::pipeline::{BindGroupDescriptor, BindGroupDescriptorId, PipelineSpecialization};
|
||||
use super::{BindGroup, BindGroupId, BufferId, RenderResourceId, SamplerId, TextureId};
|
||||
use crate::pipeline::{BindGroupDescriptor, BindGroupDescriptorId};
|
||||
use std::{
|
||||
collections::{HashMap, HashSet},
|
||||
hash::Hash,
|
||||
|
@ -20,24 +20,24 @@ pub enum RenderResourceBinding {
|
|||
|
||||
impl RenderResourceBinding {
|
||||
pub fn get_texture(&self) -> Option<TextureId> {
|
||||
if let RenderResourceBinding::Texture(texture) = self{
|
||||
Some(*texture)
|
||||
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)
|
||||
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)
|
||||
if let RenderResourceBinding::Sampler(sampler) = self {
|
||||
Some(*sampler)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
|
@ -73,16 +73,18 @@ pub enum BindGroupStatus {
|
|||
}
|
||||
|
||||
// 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)]
|
||||
#[derive(Eq, PartialEq, Debug, Default, Clone)]
|
||||
pub struct RenderResourceBindings {
|
||||
// TODO: remove this. it shouldn't be needed anymore
|
||||
pub id: RenderResourceBindingsId,
|
||||
bindings: HashMap<String, RenderResourceBinding>,
|
||||
// TODO: remove this
|
||||
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,
|
||||
// TODO: remove this
|
||||
// pub pipeline_specialization: PipelineSpecialization,
|
||||
}
|
||||
|
||||
impl RenderResourceBindings {
|
||||
|
@ -111,8 +113,7 @@ impl RenderResourceBindings {
|
|||
self.set(name, binding.clone());
|
||||
}
|
||||
|
||||
for (name, (vertex_buffer, index_buffer)) in
|
||||
render_resource_bindings.vertex_buffers.iter()
|
||||
for (name, (vertex_buffer, index_buffer)) in render_resource_bindings.vertex_buffers.iter()
|
||||
{
|
||||
self.set_vertex_buffer(name, *vertex_buffer, index_buffer.clone());
|
||||
}
|
||||
|
@ -132,16 +133,12 @@ impl RenderResourceBindings {
|
|||
.insert(name.to_string(), (vertex_buffer, index_buffer));
|
||||
}
|
||||
|
||||
fn create_bind_group(
|
||||
&mut self,
|
||||
descriptor: &BindGroupDescriptor,
|
||||
) -> BindGroupStatus {
|
||||
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);
|
||||
self.bind_group_descriptors.insert(descriptor.id, id);
|
||||
BindGroupStatus::Changed(id)
|
||||
} else {
|
||||
BindGroupStatus::NoMatch
|
||||
|
@ -152,10 +149,7 @@ impl RenderResourceBindings {
|
|||
&mut self,
|
||||
bind_group_descriptor: &BindGroupDescriptor,
|
||||
) -> BindGroupStatus {
|
||||
if let Some(id) = self
|
||||
.bind_group_descriptors
|
||||
.get(&bind_group_descriptor.id)
|
||||
{
|
||||
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)
|
||||
|
@ -171,26 +165,18 @@ impl RenderResourceBindings {
|
|||
self.bind_groups.get(&id)
|
||||
}
|
||||
|
||||
pub fn get_descriptor_bind_group(
|
||||
&self,
|
||||
id: BindGroupDescriptorId,
|
||||
) -> Option<&BindGroup> {
|
||||
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)
|
||||
})
|
||||
.and_then(|bind_group_id| self.get_bind_group(*bind_group_id))
|
||||
}
|
||||
|
||||
fn build_bind_group(
|
||||
&self,
|
||||
bind_group_descriptor: &BindGroupDescriptor,
|
||||
) -> Option<BindGroup> {
|
||||
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());
|
||||
bind_group_builder =
|
||||
bind_group_builder.add_binding(binding_descriptor.index, binding.clone());
|
||||
} else {
|
||||
return None;
|
||||
}
|
||||
|
@ -271,7 +257,8 @@ mod tests {
|
|||
panic!("expected a changed bind group");
|
||||
};
|
||||
|
||||
let different_bind_group_status = different_bindings.update_bind_group(&bind_group_descriptor);
|
||||
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,
|
||||
|
@ -284,14 +271,18 @@ mod tests {
|
|||
|
||||
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");
|
||||
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);
|
||||
let unmatched_bind_group_status =
|
||||
unmatched_bindings.update_bind_group(&bind_group_descriptor);
|
||||
assert_eq!(unmatched_bind_group_status, BindGroupStatus::NoMatch);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
use crate::{
|
||||
draw::RenderPipelines,
|
||||
pipeline::{PipelineCompiler, PipelineDescriptor},
|
||||
pipeline::{PipelineCompiler, PipelineDescriptor, RenderPipelines},
|
||||
render_resource::{BindGroupStatus, RenderResourceBindings},
|
||||
renderer::RenderResourceContext,
|
||||
};
|
||||
|
@ -56,11 +55,11 @@ pub fn bind_groups_system(
|
|||
}
|
||||
for mut render_pipelines in query.iter_mut(world) {
|
||||
let render_pipelines = render_pipelines.as_mut();
|
||||
for pipeline in render_pipelines.compiled_pipelines.iter() {
|
||||
let pipeline = pipelines.get(pipeline).unwrap();
|
||||
for render_pipeline in render_pipelines.pipelines.iter_mut() {
|
||||
let pipeline = pipelines.get(&render_pipeline.specialized_pipeline.unwrap()).unwrap();
|
||||
update_bind_groups(
|
||||
pipeline,
|
||||
&mut render_pipelines.render_resource_bindings,
|
||||
&mut render_pipelines.bindings,
|
||||
render_resource_context,
|
||||
)
|
||||
}
|
||||
|
|
|
@ -60,12 +60,13 @@ where
|
|||
T: ShaderDefs + Send + Sync + 'static,
|
||||
{
|
||||
for shader_def in shader_defs.iter_shader_defs() {
|
||||
render_pipelines
|
||||
.render_resource_bindings
|
||||
.pipeline_specialization
|
||||
.shader_specialization
|
||||
.shader_defs
|
||||
.insert(shader_def.to_string());
|
||||
for render_pipeline in render_pipelines.pipelines.iter_mut() {
|
||||
render_pipeline
|
||||
.specialization
|
||||
.shader_specialization
|
||||
.shader_defs
|
||||
.insert(shader_def.to_string());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -78,11 +79,12 @@ 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_bindings
|
||||
.pipeline_specialization
|
||||
.shader_specialization
|
||||
.shader_defs
|
||||
.insert(shader_def.to_string());
|
||||
for render_pipeline in render_pipelines.pipelines.iter_mut() {
|
||||
render_pipeline
|
||||
.specialization
|
||||
.shader_specialization
|
||||
.shader_defs
|
||||
.insert(shader_def.to_string());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,9 +2,9 @@ use crate::{
|
|||
render::SPRITE_PIPELINE_HANDLE, sprite::Sprite, ColorMaterial, Quad, TextureAtlas,
|
||||
TextureAtlasSprite, QUAD_HANDLE, SPRITE_SHEET_PIPELINE_HANDLE,
|
||||
};
|
||||
use bevy_asset::Handle;
|
||||
use bevy_app::EntityArchetype;
|
||||
use bevy_render::{mesh::Mesh, draw::{Draw, RenderPipelines}};
|
||||
use bevy_asset::Handle;
|
||||
use bevy_render::{draw::Draw, mesh::Mesh, pipeline::RenderPipelines};
|
||||
|
||||
#[derive(EntityArchetype)]
|
||||
pub struct SpriteEntity {
|
||||
|
@ -24,10 +24,7 @@ impl Default for SpriteEntity {
|
|||
mesh: QUAD_HANDLE,
|
||||
material: Default::default(),
|
||||
draw: Default::default(),
|
||||
render_pipelines: RenderPipelines {
|
||||
pipelines: vec![SPRITE_PIPELINE_HANDLE],
|
||||
..Default::default()
|
||||
},
|
||||
render_pipelines: RenderPipelines::from_handles(&[SPRITE_PIPELINE_HANDLE]),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -51,10 +48,7 @@ impl Default for SpriteSheetEntity {
|
|||
sprite: Default::default(),
|
||||
texture_atlas: Default::default(),
|
||||
draw: Default::default(),
|
||||
render_pipelines: RenderPipelines {
|
||||
pipelines: vec![SPRITE_SHEET_PIPELINE_HANDLE],
|
||||
..Default::default()
|
||||
},
|
||||
render_pipelines: RenderPipelines::from_handles(&[SPRITE_SHEET_PIPELINE_HANDLE]),
|
||||
mesh: QUAD_HANDLE,
|
||||
// transform: Default::default(),
|
||||
// translation: Default::default(),
|
||||
|
|
|
@ -2,7 +2,7 @@ use super::Node;
|
|||
use crate::{render::UI_PIPELINE_HANDLE, widget::Label};
|
||||
use bevy_asset::Handle;
|
||||
use bevy_derive::EntityArchetype;
|
||||
use bevy_render::{draw::{Draw, RenderPipelines}, mesh::Mesh};
|
||||
use bevy_render::{draw::Draw, mesh::Mesh, pipeline::RenderPipelines};
|
||||
use bevy_sprite::{ColorMaterial, Quad, QUAD_HANDLE};
|
||||
|
||||
#[derive(EntityArchetype)]
|
||||
|
@ -23,10 +23,7 @@ impl Default for UiEntity {
|
|||
mesh: QUAD_HANDLE,
|
||||
material: Default::default(),
|
||||
draw: Default::default(),
|
||||
render_pipelines: RenderPipelines {
|
||||
pipelines: vec![UI_PIPELINE_HANDLE],
|
||||
..Default::default()
|
||||
},
|
||||
render_pipelines: RenderPipelines::from_handles(&[UI_PIPELINE_HANDLE]),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -51,10 +48,7 @@ impl Default for LabelEntity {
|
|||
// NOTE: labels each get their own material.
|
||||
material: Handle::new(), // TODO: maybe abstract this out
|
||||
draw: Default::default(),
|
||||
render_pipelines: RenderPipelines {
|
||||
pipelines: vec![UI_PIPELINE_HANDLE],
|
||||
..Default::default()
|
||||
},
|
||||
render_pipelines: RenderPipelines::from_handles(&[UI_PIPELINE_HANDLE]),
|
||||
label: Label::default(),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -53,7 +53,10 @@ fn setup(
|
|||
fragment: Some(shaders.add(Shader::from_glsl(ShaderStage::Fragment, FRAGMENT_SHADER))),
|
||||
}));
|
||||
|
||||
render_graph.add_system_node("my_material", AssetRenderResourcesNode::<MyMaterial>::new(true));
|
||||
render_graph.add_system_node(
|
||||
"my_material",
|
||||
AssetRenderResourcesNode::<MyMaterial>::new(true),
|
||||
);
|
||||
pipeline_handle
|
||||
};
|
||||
|
||||
|
@ -68,10 +71,7 @@ fn setup(
|
|||
// cube
|
||||
.add_entity(MeshMaterialEntity::<MyMaterial> {
|
||||
mesh: cube_handle,
|
||||
render_pipelines: RenderPipelines {
|
||||
pipelines: vec![pipeline_handle],
|
||||
..Default::default()
|
||||
},
|
||||
render_pipelines: RenderPipelines::from_handles(&[pipeline_handle]),
|
||||
material,
|
||||
translation: Translation::new(0.0, 0.0, 0.0),
|
||||
..Default::default()
|
||||
|
|
|
@ -85,10 +85,7 @@ fn setup(
|
|||
// cube
|
||||
.add_entity(MeshMaterialEntity::<MyMaterial> {
|
||||
mesh: cube_handle,
|
||||
render_pipelines: RenderPipelines {
|
||||
pipelines: vec![pipeline_handle],
|
||||
..Default::default()
|
||||
},
|
||||
render_pipelines: RenderPipelines::from_handles(&[pipeline_handle]),
|
||||
material: green_material,
|
||||
translation: Translation::new(-2.0, 0.0, 0.0),
|
||||
..Default::default()
|
||||
|
@ -96,10 +93,7 @@ fn setup(
|
|||
// cube
|
||||
.add_entity(MeshMaterialEntity::<MyMaterial> {
|
||||
mesh: cube_handle,
|
||||
render_pipelines: RenderPipelines {
|
||||
pipelines: vec![pipeline_handle],
|
||||
..Default::default()
|
||||
},
|
||||
render_pipelines: RenderPipelines::from_handles(&[pipeline_handle]),
|
||||
material: red_material,
|
||||
translation: Translation::new(2.0, 0.0, 0.0),
|
||||
..Default::default()
|
||||
|
|
|
@ -14,20 +14,20 @@ pub use crate::{
|
|||
pbr::{entity::*, light::Light, material::StandardMaterial},
|
||||
property::{DynamicProperties, Properties, PropertiesVal, Property, PropertyVal},
|
||||
render::{
|
||||
draw::Draw,
|
||||
entity::*,
|
||||
mesh::{shape, Mesh},
|
||||
pipeline::PipelineDescriptor,
|
||||
pipeline::{PipelineDescriptor, RenderPipelines},
|
||||
render_graph::{
|
||||
nodes::{
|
||||
AssetRenderResourcesNode, CameraNode, MainPassNode, RenderResourcesNode, WindowSwapChainNode,
|
||||
WindowTextureNode,
|
||||
AssetRenderResourcesNode, CameraNode, MainPassNode, RenderResourcesNode,
|
||||
WindowSwapChainNode, WindowTextureNode,
|
||||
},
|
||||
RenderGraph,
|
||||
},
|
||||
render_resource::RenderResources,
|
||||
shader::{Shader, ShaderDefs, ShaderStage, ShaderStages},
|
||||
texture::Texture,
|
||||
draw::{Draw, RenderPipelines},
|
||||
Camera, Color, ColorSource, OrthographicProjection, PerspectiveProjection,
|
||||
},
|
||||
scene::{Scene, SceneSpawner},
|
||||
|
|
Loading…
Reference in a new issue