rafx_framework/resources/
material.rs1use crate::{
2 DescriptorSetWriteSet, FixedFunctionState, MaterialPassResource, MaterialPassVertexInput,
3 RafxResult, ReflectedShader, ResourceArc, ResourceContext, ShaderModuleResource,
4 SlotNameLookup,
5};
6use rafx_api::{RafxReflectedEntryPoint, RafxShaderStageFlags};
7use serde::{Deserialize, Serialize};
8use std::ops::Deref;
9use std::sync::Arc;
10
11#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
12pub enum MaterialShaderStage {
13 Vertex,
14 TessellationControl,
15 TessellationEvaluation,
16 Geometry,
17 Fragment,
18 Compute,
19}
20
21impl Into<RafxShaderStageFlags> for MaterialShaderStage {
22 fn into(self) -> RafxShaderStageFlags {
23 match self {
24 MaterialShaderStage::Vertex => RafxShaderStageFlags::VERTEX,
25 MaterialShaderStage::TessellationControl => RafxShaderStageFlags::TESSELLATION_CONTROL,
26 MaterialShaderStage::TessellationEvaluation => {
27 RafxShaderStageFlags::TESSELLATION_EVALUATION
28 }
29 MaterialShaderStage::Geometry => RafxShaderStageFlags::GEOMETRY,
30 MaterialShaderStage::Fragment => RafxShaderStageFlags::FRAGMENT,
31 MaterialShaderStage::Compute => RafxShaderStageFlags::COMPUTE,
32 }
33 }
34}
35
36pub struct MaterialPassInner {
37 pub shader_modules: Vec<ResourceArc<ShaderModuleResource>>,
38
39 pub material_pass_resource: ResourceArc<MaterialPassResource>,
41
42 pub vertex_inputs: Arc<Vec<MaterialPassVertexInput>>,
44
45 pub pass_slot_name_lookup: Arc<SlotNameLookup>,
48 }
52
53#[derive(Clone)]
54pub struct MaterialPass {
55 inner: Arc<MaterialPassInner>,
56}
57
58impl MaterialPass {
59 pub fn new(
60 resource_context: &ResourceContext,
61 debug_name: Option<&str>,
62 fixed_function_state: Arc<FixedFunctionState>,
63 shader_modules: Vec<ResourceArc<ShaderModuleResource>>,
64 entry_points: &[&RafxReflectedEntryPoint],
65 ) -> RafxResult<MaterialPass> {
66 let reflected_shader =
67 ReflectedShader::new(resource_context.resources(), &shader_modules, entry_points)?;
68
69 let material_pass = reflected_shader.load_material_pass(
70 resource_context.resources(),
71 fixed_function_state,
72 debug_name,
73 )?;
74
75 let vertex_inputs = reflected_shader
76 .metadata
77 .vertex_inputs
78 .ok_or_else(|| "The material pass does not specify a vertex shader")?;
79
80 let inner = MaterialPassInner {
81 shader_modules,
82 material_pass_resource: material_pass.clone(),
83 pass_slot_name_lookup: Arc::new(reflected_shader.metadata.slot_name_lookup),
84 vertex_inputs,
85 };
86
87 Ok(MaterialPass {
88 inner: Arc::new(inner),
89 })
90 }
91
92 pub fn create_uninitialized_write_sets_for_material_pass(&self) -> Vec<DescriptorSetWriteSet> {
93 let pass_descriptor_set_writes: Vec<_> = self
95 .inner
96 .material_pass_resource
97 .get_raw()
98 .descriptor_set_layouts
99 .iter()
100 .map(|layout| {
101 super::descriptor_sets::create_uninitialized_write_set_for_layout(
102 &layout.get_raw().descriptor_set_layout_def,
103 )
104 })
105 .collect();
106
107 pass_descriptor_set_writes
108 }
109}
110
111impl Deref for MaterialPass {
112 type Target = MaterialPassInner;
113
114 fn deref(&self) -> &Self::Target {
115 &*self.inner
116 }
117}