summaryrefslogtreecommitdiff
path: root/engine
diff options
context:
space:
mode:
Diffstat (limited to 'engine')
-rw-r--r--engine/src/renderer.rs128
-rw-r--r--engine/src/renderer/opengl.rs7
-rw-r--r--engine/src/shader.rs5
3 files changed, 116 insertions, 24 deletions
diff --git a/engine/src/renderer.rs b/engine/src/renderer.rs
index 7865ac4..a04fd4f 100644
--- a/engine/src/renderer.rs
+++ b/engine/src/renderer.rs
@@ -4,11 +4,13 @@ use std::sync::atomic::{AtomicU64, Ordering};
use bitflags::bitflags;
use ecs::actions::Actions;
+use ecs::entity::obtainer::Obtainer as EntityObtainer;
use ecs::pair::{ChildOf, Pair, Wildcard};
use ecs::phase::{POST_UPDATE as POST_UPDATE_PHASE, Phase};
-use ecs::query::term::Without;
+use ecs::query::term::{With, Without};
use ecs::sole::Single;
-use ecs::{Component, Query, declare_entity};
+use ecs::uid::Uid;
+use ecs::{Component, Query, Sole, declare_entity};
use crate::asset::{Assets, Handle as AssetHandle};
use crate::builder;
@@ -142,6 +144,20 @@ impl SurfaceId
}
}
+#[derive(Debug, Default, Sole)]
+pub struct RenderPasses
+{
+ pub passes: VecDeque<RenderPass>,
+}
+
+#[derive(Debug)]
+pub struct RenderPass
+{
+ pub renderer_ctx_ent_id: Uid,
+ pub surface_id: SurfaceId,
+ pub commands: Vec<Command>,
+}
+
#[derive(Debug)]
#[non_exhaustive]
pub enum Command
@@ -211,15 +227,15 @@ type RenderableEntity<'a> = (
);
#[tracing::instrument(skip_all)]
-pub fn enqueue_commands(
- renderer_ctx_query: Query<(
- &mut CommandQueue,
- &ObjectStore,
- &[Pair<CtxUsedByWindow, Wildcard>],
- )>,
+pub fn add_main_render_passes(
+ renderer_ctx_query: Query<
+ (&ObjectStore, &[Pair<CtxUsedByWindow, Wildcard>]),
+ (With<CommandQueue>,),
+ >,
renderable_query: Query<RenderableEntity<'_>, (Without<NoDraw>,)>,
assets: Single<Assets>,
shader_context: Single<ShaderContext>,
+ mut render_passes: Single<RenderPasses>,
mut actions: Actions,
)
{
@@ -230,7 +246,7 @@ pub fn enqueue_commands(
return;
};
- for (renderer_ctx_ent_id, (mut command_queue, object_store, used_by_windows)) in
+ for (renderer_ctx_ent_id, (object_store, used_by_windows)) in
renderer_ctx_query.iter_with_euids()
{
for ctx_used_by_window in used_by_windows {
@@ -269,7 +285,17 @@ pub fn enqueue_commands(
continue;
};
- command_queue.push(Command::MakeCurrent(surface_spec.id));
+ render_passes.passes.push_front(RenderPass {
+ renderer_ctx_ent_id,
+ surface_id: surface_spec.id,
+ commands: Vec::with_capacity(30),
+ });
+
+ let render_pass = render_passes.passes.front_mut().expect("Not possible");
+
+ render_pass
+ .commands
+ .push(Command::MakeCurrent(surface_spec.id));
let default_texture_asset = assets
.get_handle_to_loaded::<Texture>(TEXTURE_WHITE_1X1_ASSET_LABEL.clone())
@@ -278,10 +304,12 @@ pub fn enqueue_commands(
if !object_store
.contains_with_id(&ObjectId::Asset(default_texture_asset.id()))
{
- command_queue.push(Command::CreateTexture(default_texture_asset));
+ render_pass
+ .commands
+ .push(Command::CreateTexture(default_texture_asset));
}
- command_queue.push(Command::ClearBuffers(
+ render_pass.commands.push(Command::ClearBuffers(
BufferClearMask::COLOR | BufferClearMask::DEPTH,
));
@@ -337,13 +365,14 @@ pub fn enqueue_commands(
continue;
};
- command_queue.push(Command::CreateShaderProgram(
+ render_pass.commands.push(Command::CreateShaderProgram(
ObjectId::Asset(shader_asset.id()),
shader_program.clone(),
));
}
- command_queue
+ render_pass
+ .commands
.push(Command::ActivateShader(ObjectId::Asset(shader_asset.id())));
let Some(model_material) = assets.get(&model_material_asset) else {
@@ -362,7 +391,9 @@ pub fn enqueue_commands(
if !object_store
.contains_with_id(&ObjectId::Asset(texture_asset.id()))
{
- command_queue.push(Command::CreateTexture(texture_asset.clone()));
+ render_pass
+ .commands
+ .push(Command::CreateTexture(texture_asset.clone()));
}
}
@@ -370,7 +401,7 @@ pub fn enqueue_commands(
for (shader_binding_loc, shader_binding_val) in
pending_shader_bindings.bindings.drain(..)
{
- command_queue.push(Command::SetShaderBinding(
+ render_pass.commands.push(Command::SetShaderBinding(
shader_binding_loc,
shader_binding_val,
));
@@ -380,28 +411,85 @@ pub fn enqueue_commands(
if let Some(draw_flags) = draw_flags.as_deref()
&& draw_flags.polygon_mode_config != PolygonModeConfig::default()
{
- command_queue.push(Command::SetPolygonModeConfig(
+ render_pass.commands.push(Command::SetPolygonModeConfig(
draw_flags.polygon_mode_config.clone(),
));
}
if !object_store.contains_with_id(&ObjectId::Asset(mesh_asset.id())) {
- command_queue.push(Command::CreateMesh(
+ render_pass.commands.push(Command::CreateMesh(
ObjectId::Asset(mesh_asset.id()),
mesh.clone(),
));
}
- command_queue.push(Command::DrawMesh(ObjectId::Asset(mesh_asset.id())));
+ render_pass
+ .commands
+ .push(Command::DrawMesh(ObjectId::Asset(mesh_asset.id())));
if let Some(draw_flags) = draw_flags.as_deref()
&& draw_flags.polygon_mode_config != PolygonModeConfig::default()
{
- command_queue.push(Command::SetPolygonModeConfig(
+ render_pass.commands.push(Command::SetPolygonModeConfig(
PolygonModeConfig::default(),
));
}
}
+ }
+ }
+}
+
+#[tracing::instrument(skip_all)]
+pub fn enqueue_commands_from_render_passes(
+ renderer_ctx_query: Query<(&mut CommandQueue, &[Pair<CtxUsedByWindow, Wildcard>])>,
+ mut render_passes: Single<RenderPasses>,
+ entity_obtainer: EntityObtainer,
+)
+{
+ for render_pass in render_passes.passes.drain(..) {
+ let Some(renderer_ctx_ent) =
+ entity_obtainer.get_entity(render_pass.renderer_ctx_ent_id)
+ else {
+ tracing::error!(
+ renderer_ctx_entity_id=%render_pass.renderer_ctx_ent_id,
+ "Renderer context entity does not exist"
+ );
+
+ continue;
+ };
+
+ let Some(mut renderer_ctx_command_queue) =
+ renderer_ctx_ent.get_mut::<CommandQueue>()
+ else {
+ tracing::error!(
+ renderer_ctx_entity_id=%render_pass.renderer_ctx_ent_id,
+ "Renderer context entity does not have a command queue component"
+ );
+ continue;
+ };
+
+ renderer_ctx_command_queue
+ .queue
+ .extend(render_pass.commands);
+ }
+
+ for (mut command_queue, used_by_windows) in &renderer_ctx_query {
+ for ctx_used_by_window in used_by_windows {
+ let window_ent_id = ctx_used_by_window.id().target_entity();
+
+ let Some(window_ent) = ctx_used_by_window.get_target_ent() else {
+ tracing::error!("Window entity does not exist");
+ continue;
+ };
+
+ let Some(surface_spec) = window_ent.get::<SurfaceSpec>() else {
+ tracing::debug!(
+ window_entity_id=%window_ent_id,
+ "Window entity does not have a {} component",
+ type_name::<SurfaceSpec>()
+ );
+ continue;
+ };
command_queue.push(Command::SwapBuffers(surface_spec.id));
}
diff --git a/engine/src/renderer/opengl.rs b/engine/src/renderer/opengl.rs
index 261148b..5ed2aaa 100644
--- a/engine/src/renderer/opengl.rs
+++ b/engine/src/renderer/opengl.rs
@@ -86,6 +86,7 @@ use crate::renderer::{
GraphicsProperties,
PRE_RENDER_PHASE,
RENDER_PHASE,
+ RenderPasses,
SurfaceId,
SurfaceSpec,
WindowUsingRendererCtx,
@@ -159,7 +160,11 @@ impl ecs::extension::Extension for Extension
collector.add_declared_entity(&RENDER_PHASE);
collector.add_declared_entity(&POST_RENDER_PHASE);
- collector.add_system(*RENDER_PHASE, super::enqueue_commands);
+ let _ = collector.add_sole(RenderPasses::default());
+
+ collector.add_system(*PRE_RENDER_PHASE, super::add_main_render_passes);
+
+ collector.add_system(*RENDER_PHASE, super::enqueue_commands_from_render_passes);
collector.add_system(*RENDER_PHASE, handle_commands);
collector.add_system(*POST_RENDER_PHASE, prepare_windows);
diff --git a/engine/src/shader.rs b/engine/src/shader.rs
index ae0be1d..2b16c47 100644
--- a/engine/src/shader.rs
+++ b/engine/src/shader.rs
@@ -8,7 +8,7 @@ use std::str::Utf8Error;
use bitflags::{bitflags, bitflags_match};
use ecs::pair::{ChildOf, Pair};
-use ecs::phase::{Phase, START as START_PHASE};
+use ecs::phase::{POST_UPDATE as POST_UPDATE_PHASE, Phase, START as START_PHASE};
use ecs::sole::Single;
use ecs::{Component, Sole, declare_entity};
use shader_slang::{
@@ -38,7 +38,6 @@ use crate::reflection::{
StructField as StructFieldReflection,
With,
};
-use crate::renderer::PRE_RENDER_PHASE;
use crate::shader::default::{
ASSET_LABEL,
enqueue_set_shader_bindings as default_shader_enqueue_set_shader_bindings,
@@ -977,7 +976,7 @@ impl ecs::extension::Extension for Extension
collector.add_system(*IMPORT_SHADERS_PHASE, load_modules);
collector.add_system(
- *PRE_RENDER_PHASE,
+ *POST_UPDATE_PHASE,
default_shader_enqueue_set_shader_bindings,
);
}