summaryrefslogtreecommitdiff
path: root/engine/src/rendering/shader/cursor.rs
diff options
context:
space:
mode:
Diffstat (limited to 'engine/src/rendering/shader/cursor.rs')
-rw-r--r--engine/src/rendering/shader/cursor.rs116
1 files changed, 113 insertions, 3 deletions
diff --git a/engine/src/rendering/shader/cursor.rs b/engine/src/rendering/shader/cursor.rs
index 8aab4f2..32dee00 100644
--- a/engine/src/rendering/shader/cursor.rs
+++ b/engine/src/rendering/shader/cursor.rs
@@ -1,8 +1,16 @@
+use std::hint::cold_path;
+
use crate::color::Color;
use crate::data_types::matrix::Matrix;
use crate::data_types::vector::Vec3;
use crate::rendering::object::Id as RenderingObjectId;
-use crate::rendering::shader::{TypeKind, TypeLayout, VariableLayout};
+use crate::rendering::shader::{
+ ResourceShape,
+ ScalarType,
+ TypeKind,
+ TypeLayout,
+ VariableLayout,
+};
/// Shader cursor
#[derive(Clone)]
@@ -89,9 +97,14 @@ impl<'a> Cursor<'a>
self
}
- pub fn binding_location(&self) -> &BindingLocation
+ pub fn binding(self, value: BindingValue) -> Result<Binding, BindingError>
{
- &self.binding_location
+ value.validate_for_shader_type(self.type_layout)?;
+
+ Ok(Binding {
+ location: self.binding_location,
+ value,
+ })
}
pub fn into_binding_location(self) -> BindingLocation
@@ -120,6 +133,84 @@ pub enum BindingValue
Texture(RenderingObjectId),
}
+impl BindingValue
+{
+ fn validate_for_shader_type(&self, ty: TypeLayout<'_>) -> Result<(), BindingError>
+ {
+ match (
+ self,
+ ty.kind(),
+ ty.scalar_type(),
+ ty.element_type_layout()
+ .map(|elem_ty| elem_ty.scalar_type()),
+ ty.element_cnt(),
+ ty.resource_shape(),
+ ) {
+ (Self::Uint(_), TypeKind::Scalar, Some(ScalarType::Uint32), _, _, _)
+ | (Self::Int(_), TypeKind::Scalar, Some(ScalarType::Int32), _, _, _)
+ | (Self::Float(_), TypeKind::Scalar, Some(ScalarType::Float32), _, _, _)
+ | (
+ Self::FVec3(_),
+ TypeKind::Vector,
+ _,
+ Some(Some(ScalarType::Float32)),
+ Some(3),
+ _,
+ )
+ | (
+ Self::Color(Color::Rgb(_)),
+ TypeKind::Vector,
+ _,
+ Some(Some(ScalarType::Float32)),
+ Some(3),
+ _,
+ )
+ | (
+ Self::Color(Color::Rgba(_)),
+ TypeKind::Vector,
+ _,
+ Some(Some(ScalarType::Float32)),
+ Some(4),
+ _,
+ )
+ | (
+ Self::Color(Color::Luma(_)),
+ TypeKind::Vector,
+ _,
+ Some(Some(ScalarType::Float32)),
+ Some(1),
+ _,
+ )
+ | (
+ Self::Color(Color::LumaA(_)),
+ TypeKind::Vector,
+ _,
+ Some(Some(ScalarType::Float32)),
+ Some(2),
+ _,
+ ) => Ok(()),
+ (
+ Self::FMat4x4(_),
+ TypeKind::Matrix,
+ _,
+ Some(Some(ScalarType::Float32)),
+ _,
+ _,
+ ) if ty.row_cnt() == Some(4) && ty.column_cnt() == Some(4) => Ok(()),
+ (Self::Texture(_), TypeKind::Resource, _, _, _, Some(res_shape))
+ if (res_shape & ResourceShape::BASE)
+ .contains(ResourceShape::TEXTURE_2D) =>
+ {
+ Ok(())
+ }
+ _ => {
+ cold_path();
+ Err(BindingError::IncorrectValueType { value: self.clone() })
+ }
+ }
+ }
+}
+
impl From<u32> for BindingValue
{
fn from(value: u32) -> Self
@@ -167,3 +258,22 @@ impl From<Matrix<f32, 4, 4>> for BindingValue
BindingValue::FMat4x4(matrix)
}
}
+
+#[derive(Debug, Clone)]
+#[non_exhaustive]
+pub struct Binding
+{
+ pub location: BindingLocation,
+ pub value: BindingValue,
+}
+
+#[derive(Debug, thiserror::Error)]
+#[non_exhaustive]
+pub enum BindingError
+{
+ #[error("Value {value:?} has incorrect type for shader binding location")]
+ IncorrectValueType
+ {
+ value: BindingValue
+ },
+}