diff options
Diffstat (limited to 'engine/src/rendering/shader/cursor.rs')
| -rw-r--r-- | engine/src/rendering/shader/cursor.rs | 116 |
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 + }, +} |
