summaryrefslogtreecommitdiff
path: root/engine/src/rendering/backend
diff options
context:
space:
mode:
Diffstat (limited to 'engine/src/rendering/backend')
-rw-r--r--engine/src/rendering/backend/opengl.rs100
1 files changed, 79 insertions, 21 deletions
diff --git a/engine/src/rendering/backend/opengl.rs b/engine/src/rendering/backend/opengl.rs
index 0a04d6e..bdaa555 100644
--- a/engine/src/rendering/backend/opengl.rs
+++ b/engine/src/rendering/backend/opengl.rs
@@ -6,6 +6,7 @@ use std::convert::Infallible;
use std::hint::cold_path;
use std::num::NonZero;
+use ecs::phase::INIT as INIT_PHASE;
use ecs::query::term::With;
use glutin::config::Config as GlutinConfig;
use glutin::display::GetGlDisplay;
@@ -116,14 +117,17 @@ use crate::rendering::shader::cursor::{
BindingLocation as ShaderBindingLocation,
BindingValue as ShaderBindingValue,
};
+use crate::rendering::shader::reflection::Stage as ShaderStage;
use crate::rendering::shader::{
+ EntrypointFlags as ShaderEntrypointFlags,
Error as ShaderError,
Program as ShaderProgram,
- ProgramMetadata as ShaderProgramMetadata,
- Stage as ShaderStage,
+ VertexDescCreationError as ShaderVertexDescCreationError,
+ VertexDescription as ShaderVertexDescription,
};
use crate::rendering::{
AssetOrValue,
+ BackendProperties,
BufferClearMask,
Command,
CommandQueue,
@@ -436,7 +440,7 @@ enum BackendResource
Shader
{
program: GlShaderProgram,
- program_metadata: ShaderProgramMetadata,
+ info: ShaderInfo,
bindings: IntMap<ShaderBindingIndex, BackendShaderBinding>,
},
Texture
@@ -489,6 +493,14 @@ enum TextureKind
CubeMap,
}
+#[derive(Debug, Clone)]
+struct ShaderInfo
+{
+ /// If the shader program has a entry point in the vertex stage, this field will
+ /// contain a description of the vertex type passed to the entry point.
+ vertex_desc: Option<ShaderVertexDescription>,
+}
+
#[derive(Debug, Default)]
#[non_exhaustive]
pub struct Extension {}
@@ -497,6 +509,8 @@ impl crate::ecs::extension::Extension for Extension
{
fn collect(self, mut collector: crate::ecs::extension::Collector<'_>)
{
+ collector.add_system(*INIT_PHASE, init);
+
collector.add_system(*RENDER_PHASE, handle_commands);
collector.add_system(*POST_RENDER_PHASE, prepare_windows);
@@ -506,6 +520,24 @@ impl crate::ecs::extension::Extension for Extension
}
}
+fn init(
+ mut shader_context: Single<crate::rendering::shader::Context>,
+ mut actions: Actions,
+) -> Result<(), crate::Error>
+{
+ let shader_context = shader_context.get_mut()?;
+
+ let shader_target_ids = shader_context
+ .init_session(&[&crate::rendering::shader::CompileTarget::default()
+ .format(crate::rendering::shader::CompileTargetFormat::Glsl)])?;
+
+ actions.create_sole(BackendProperties {
+ shader_target_id: shader_target_ids[0],
+ });
+
+ Ok(())
+}
+
fn prepare_windows(
window_query: Query<(
Option<&Window>,
@@ -756,6 +788,7 @@ fn handle_commands(
mut object_store: Single<ObjectStore>,
mut command_queue: Single<CommandQueue>,
assets: Single<Assets>,
+ backend_properties: Single<BackendProperties>,
) -> Result<(), crate::Error>
{
let Ok(graphics_ctx) = graphics_ctx.get_mut() else {
@@ -766,6 +799,10 @@ fn handle_commands(
let command_queue = command_queue.get_mut()?;
let assets = assets.get()?;
+ let Ok(backend_properties) = backend_properties.get() else {
+ return Ok(());
+ };
+
let GraphicsContext {
ref gl_context,
ref mut surfaces,
@@ -776,11 +813,8 @@ fn handle_commands(
return Ok(());
};
- let mut activated_gl_shader_program: Option<(
- ObjectId,
- GlShaderProgram,
- ShaderProgramMetadata,
- )> = None;
+ let mut activated_gl_shader_program: Option<(ObjectId, GlShaderProgram, ShaderInfo)> =
+ None;
for command in command_queue.drain() {
let tracing_span = tracing::info_span!(
@@ -895,8 +929,21 @@ fn handle_commands(
program: create_shader_program(
gl_context,
&shader_program,
+ backend_properties,
)?,
- program_metadata: shader_program.metadata().clone(),
+ info: ShaderInfo {
+ vertex_desc: if shader_program
+ .metadata()
+ .link_entrypoints
+ .contains(ShaderEntrypointFlags::VERTEX)
+ {
+ Some(shader_program.create_vertex_desc(
+ backend_properties.shader_target_id,
+ )?)
+ } else {
+ None
+ },
+ },
bindings: IntMap::with_capacity(4),
})
},
@@ -914,7 +961,7 @@ fn handle_commands(
continue;
};
- let BackendResource::Shader { program, program_metadata, bindings } =
+ let BackendResource::Shader { program, info: shader_info, bindings } =
resource
else {
unreachable!();
@@ -927,7 +974,7 @@ fn handle_commands(
}
activated_gl_shader_program =
- Some((shader_object_id, program.clone(), program_metadata.clone()));
+ Some((shader_object_id, program.clone(), shader_info.clone()));
}
Command::SetShaderBinding(
shader_object_id,
@@ -1162,7 +1209,7 @@ fn handle_commands(
unreachable!();
};
- let Some((shader_program_obj_id, _, shader_program_metadata)) =
+ let Some((shader_program_obj_id, _, shader_info)) =
&activated_gl_shader_program
else {
tracing::error!("No shader program is activated");
@@ -1174,8 +1221,7 @@ fn handle_commands(
vertex_attrs_updated_for_shader != *shader_program_obj_id
},
) {
- let Some(shader_program_vertex_desc) =
- &shader_program_metadata.vertex_desc
+ let Some(shader_program_vertex_desc) = &shader_info.vertex_desc
else {
tracing::error!(
"Activated shader program does not have a vertex description"
@@ -1799,9 +1845,12 @@ fn cube_map_texture_face_to_gl(face: CubeMapTextureFace) -> GlCubeMapTextureFace
fn create_shader_program(
current_context: &MaybeCurrentContextWithFns,
shader_program: &ShaderProgram,
+ backend_properties: &BackendProperties,
) -> Result<GlShaderProgram, CreateShaderError>
{
- let shader_program_reflection = shader_program.reflection(0).expect("Not possible");
+ let shader_program_reflection = shader_program
+ .reflection(backend_properties.shader_target_id)
+ .expect("Not possible");
let (vs_entry_point_index, vs_entry_point_reflection) = shader_program_reflection
.entry_points()
@@ -1812,9 +1861,12 @@ fn create_shader_program(
})?;
let vertex_shader_entry_point_code = shader_program
- .get_entry_point_code(vs_entry_point_index.try_into().expect(
- "Vertex shader entry point index does not fit in 32-bit unsigned int",
- ))
+ .get_entry_point_code(
+ vs_entry_point_index.try_into().expect(
+ "Vertex shader entry point index does not fit in 32-bit unsigned int",
+ ),
+ backend_properties.shader_target_id,
+ )
.map_err(|err| CreateShaderError::GetShaderEntryPointCodeFailed {
err,
stage: ShaderStage::Vertex,
@@ -1832,9 +1884,12 @@ fn create_shader_program(
})?;
let fragment_shader_entry_point_code = shader_program
- .get_entry_point_code(fs_entry_point_index.try_into().expect(
- "Fragment shader entry point index does not fit in 32-bit unsigned int",
- ))
+ .get_entry_point_code(
+ fs_entry_point_index.try_into().expect(
+ "Fragment shader entry point index does not fit in 32-bit unsigned int",
+ ),
+ backend_properties.shader_target_id,
+ )
.map_err(|err| CreateShaderError::GetShaderEntryPointCodeFailed {
err,
stage: ShaderStage::Fragment,
@@ -1888,6 +1943,9 @@ enum CreateShaderError
#[error("No entrypoint was found for shader stage {0:?}")]
NoShaderStageEntrypointFound(ShaderStage),
+ #[error("Failed to create shader vertex description")]
+ VertexDescCreationFailed(#[from] ShaderVertexDescCreationError),
+
#[error(transparent)]
ShaderError(#[from] GlShaderError),
}