1use fnv::FnvHasher;
2use std::hash::{Hash, Hasher};
3
4use crate::{RafxApiType, RafxReflectedEntryPoint};
5#[cfg(feature = "serde-support")]
6use serde::{Deserialize, Serialize};
7
8#[derive(Debug, Clone, PartialEq, Eq, Hash)]
13#[cfg_attr(feature = "serde-support", derive(Serialize, Deserialize))]
14pub enum RafxShaderPackageGles2 {
15 Src(String),
17}
18
19#[derive(Debug, Clone, PartialEq, Eq, Hash)]
24#[cfg_attr(feature = "serde-support", derive(Serialize, Deserialize))]
25pub enum RafxShaderPackageGles3 {
26 Src(String),
28}
29
30#[derive(Debug, Clone, PartialEq, Eq, Hash)]
33#[cfg_attr(feature = "serde-support", derive(Serialize, Deserialize))]
34pub enum RafxShaderPackageDx12 {
35 Src(String),
37 }
40
41#[derive(Debug, Clone, PartialEq, Eq, Hash)]
44#[cfg_attr(feature = "serde-support", derive(Serialize, Deserialize))]
45pub enum RafxShaderPackageMetal {
46 Src(String),
48 #[cfg_attr(feature = "serde-support", serde(with = "serde_bytes"))]
50 LibBytes(Vec<u8>),
51}
52
53#[derive(Debug, Clone, PartialEq, Eq, Hash)]
56#[cfg_attr(feature = "serde-support", derive(Serialize, Deserialize))]
57pub enum RafxShaderPackageVulkan {
58 #[cfg_attr(feature = "serde-support", serde(with = "serde_bytes"))]
60 SpvBytes(Vec<u8>),
61}
62
63#[derive(Debug, Clone, PartialEq, Eq, Hash)]
64#[cfg_attr(feature = "serde-support", derive(Serialize, Deserialize))]
65#[doc(hidden)]
66pub enum RafxShaderPackageEmpty {
67 Empty,
68}
69
70#[derive(Debug, Clone, PartialEq, Eq, Hash, Default)]
80#[cfg_attr(feature = "serde-support", derive(Serialize, Deserialize))]
81pub struct RafxShaderPackage {
82 pub gles2: Option<RafxShaderPackageGles2>,
83 pub gles3: Option<RafxShaderPackageGles3>,
84 pub dx12: Option<RafxShaderPackageDx12>,
85 pub metal: Option<RafxShaderPackageMetal>,
86 pub vk: Option<RafxShaderPackageVulkan>,
87
88 pub vk_reflection: Option<Vec<RafxReflectedEntryPoint>>,
89 pub dx12_reflection: Option<Vec<RafxReflectedEntryPoint>>,
90 pub metal_reflection: Option<Vec<RafxReflectedEntryPoint>>,
91 pub gles2_reflection: Option<Vec<RafxReflectedEntryPoint>>,
92 pub gles3_reflection: Option<Vec<RafxReflectedEntryPoint>>,
93
94 pub debug_name: Option<String>,
95}
96
97#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, Default)]
99#[cfg_attr(feature = "serde-support", derive(Serialize, Deserialize))]
100pub struct RafxShaderPackageHash(u64);
101impl RafxShaderPackageHash {
102 pub fn new(shader_package: &RafxShaderPackage) -> Self {
103 let mut hasher = FnvHasher::default();
104 shader_package.hash(&mut hasher);
105 let hash = hasher.finish();
106 RafxShaderPackageHash(hash)
107 }
108}
109
110#[derive(Debug, Clone, PartialEq, Eq, Hash, Default)]
113#[cfg_attr(feature = "serde-support", derive(Serialize, Deserialize))]
114pub struct RafxHashedShaderPackage {
115 shader_package_hash: RafxShaderPackageHash,
116 shader_package: RafxShaderPackage,
117}
118
119impl RafxHashedShaderPackage {
120 pub fn new(shader_package: RafxShaderPackage) -> Self {
121 let shader_package_hash = RafxShaderPackageHash::new(&shader_package);
122 RafxHashedShaderPackage {
123 shader_package_hash,
124 shader_package,
125 }
126 }
127
128 pub fn shader_package_hash(&self) -> RafxShaderPackageHash {
129 self.shader_package_hash
130 }
131
132 pub fn shader_package(&self) -> &RafxShaderPackage {
133 &self.shader_package
134 }
135}
136
137impl RafxShaderPackage {
138 pub fn reflection(
139 &self,
140 api_type: RafxApiType,
141 ) -> Option<&Vec<RafxReflectedEntryPoint>> {
142 match api_type {
143 RafxApiType::Vk => self.vk_reflection.as_ref(),
144 RafxApiType::Dx12 => self.dx12_reflection.as_ref(),
145 RafxApiType::Metal => self.metal_reflection.as_ref(),
146 RafxApiType::Gles2 => self.gles2_reflection.as_ref(),
147 RafxApiType::Gles3 => self.gles3_reflection.as_ref(),
148 RafxApiType::Empty => None,
149 }
150 }
151
152 pub fn find_entry_point(
153 &self,
154 api_type: RafxApiType,
155 entry_point_name: &str,
156 ) -> Option<&RafxReflectedEntryPoint> {
157 self.reflection(api_type)
158 .map(|x| {
159 x.iter()
160 .find(|&x| x.rafx_api_reflection.entry_point_name == entry_point_name)
161 })
162 .flatten()
163 }
164
165 #[cfg(feature = "rafx-gles2")]
168 pub fn gles2_module_def(&self) -> Option<RafxShaderModuleDefGles2> {
169 if let Some(gl) = self.gles2.as_ref() {
170 Some(match gl {
171 RafxShaderPackageGles2::Src(src) => RafxShaderModuleDefGles2::GlSrc(src),
172 })
173 } else {
174 None
175 }
176 }
177
178 #[cfg(feature = "rafx-gles3")]
181 pub fn gles3_module_def(&self) -> Option<RafxShaderModuleDefGles3> {
182 if let Some(gl) = self.gles3.as_ref() {
183 Some(match gl {
184 RafxShaderPackageGles3::Src(src) => RafxShaderModuleDefGles3::GlSrc(src),
185 })
186 } else {
187 None
188 }
189 }
190
191 #[cfg(feature = "rafx-dx12")]
194 pub fn dx12_module_def(&self) -> Option<RafxShaderModuleDefDx12> {
195 if let Some(dx12) = self.dx12.as_ref() {
196 Some(match dx12 {
197 RafxShaderPackageDx12::Src(src) => RafxShaderModuleDefDx12::HlslSrc(src),
198 })
200 } else {
201 None
202 }
203 }
204
205 #[cfg(feature = "rafx-metal")]
208 pub fn metal_module_def(&self) -> Option<RafxShaderModuleDefMetal> {
209 if let Some(metal) = self.metal.as_ref() {
210 Some(match metal {
211 RafxShaderPackageMetal::Src(src) => RafxShaderModuleDefMetal::MetalSrc(src),
212 RafxShaderPackageMetal::LibBytes(lib) => {
213 RafxShaderModuleDefMetal::MetalLibBytes(lib)
214 }
215 })
216 } else {
217 None
218 }
219 }
220
221 #[cfg(feature = "rafx-vulkan")]
224 pub fn vulkan_module_def(&self) -> Option<RafxShaderModuleDefVulkan> {
225 if let Some(vk) = self.vk.as_ref() {
226 Some(match vk {
227 RafxShaderPackageVulkan::SpvBytes(bytes) => {
228 RafxShaderModuleDefVulkan::VkSpvBytes(bytes)
229 }
230 })
231 } else {
232 None
233 }
234 }
235
236 #[cfg(any(
239 feature = "rafx-empty",
240 not(any(
241 feature = "rafx-dx12",
242 feature = "rafx-metal",
243 feature = "rafx-vulkan",
244 feature = "rafx-gles2",
245 feature = "rafx-gles3"
246 ))
247 ))]
248 #[doc(hidden)]
249 pub fn empty_module_def(&self) -> Option<RafxShaderModuleDefEmpty> {
250 Some(RafxShaderModuleDefEmpty::Empty(Default::default()))
251 }
252
253 pub fn module_def(&self) -> RafxShaderModuleDef {
254 RafxShaderModuleDef {
255 #[cfg(feature = "rafx-gles2")]
256 gles2: self.gles2_module_def(),
257 #[cfg(feature = "rafx-gles3")]
258 gles3: self.gles3_module_def(),
259 #[cfg(feature = "rafx-dx12")]
260 dx12: self.dx12_module_def(),
261 #[cfg(feature = "rafx-metal")]
262 metal: self.metal_module_def(),
263 #[cfg(feature = "rafx-vulkan")]
264 vk: self.vulkan_module_def(),
265 #[cfg(any(
266 feature = "rafx-empty",
267 not(any(
268 feature = "rafx-dx12",
269 feature = "rafx-metal",
270 feature = "rafx-vulkan",
271 feature = "rafx-gles2",
272 feature = "rafx-gles3"
273 ))
274 ))]
275 empty: self.empty_module_def(),
276 }
277 }
278}
279
280#[derive(Copy, Clone, Hash)]
284#[cfg(feature = "rafx-gles2")]
285pub enum RafxShaderModuleDefGles2<'a> {
286 GlSrc(&'a str),
288}
289
290#[derive(Copy, Clone, Hash)]
294#[cfg(feature = "rafx-gles3")]
295pub enum RafxShaderModuleDefGles3<'a> {
296 GlSrc(&'a str),
298}
299
300#[derive(Copy, Clone, Hash)]
304#[cfg(feature = "rafx-dx12")]
305pub enum RafxShaderModuleDefDx12<'a> {
306 HlslSrc(&'a str),
308 }
311
312#[derive(Copy, Clone, Hash)]
316#[cfg(feature = "rafx-metal")]
317pub enum RafxShaderModuleDefMetal<'a> {
318 MetalSrc(&'a str),
320 MetalLibBytes(&'a [u8]),
322}
323
324#[derive(Copy, Clone, Hash)]
328#[cfg(feature = "rafx-vulkan")]
329pub enum RafxShaderModuleDefVulkan<'a> {
330 VkSpvBytes(&'a [u8]),
332 VkSpvPrepared(&'a [u32]),
334}
335
336#[cfg(any(
337 feature = "rafx-empty",
338 not(any(
339 feature = "rafx-dx12",
340 feature = "rafx-metal",
341 feature = "rafx-vulkan",
342 feature = "rafx-gles2",
343 feature = "rafx-gles3"
344 ))
345))]
346#[derive(Copy, Clone, Hash)]
347#[doc(hidden)]
348pub enum RafxShaderModuleDefEmpty<'a> {
349 Empty(std::marker::PhantomData<&'a u32>),
350}
351
352#[derive(Copy, Clone, Hash, Default)]
356pub struct RafxShaderModuleDef<'a> {
357 #[cfg(feature = "rafx-gles2")]
358 pub gles2: Option<RafxShaderModuleDefGles2<'a>>,
359 #[cfg(feature = "rafx-gles3")]
360 pub gles3: Option<RafxShaderModuleDefGles3<'a>>,
361 #[cfg(feature = "rafx-dx12")]
362 pub dx12: Option<RafxShaderModuleDefDx12<'a>>,
363 #[cfg(feature = "rafx-metal")]
364 pub metal: Option<RafxShaderModuleDefMetal<'a>>,
365 #[cfg(feature = "rafx-vulkan")]
366 pub vk: Option<RafxShaderModuleDefVulkan<'a>>,
367 #[cfg(any(
368 feature = "rafx-empty",
369 not(any(
370 feature = "rafx-dx12",
371 feature = "rafx-metal",
372 feature = "rafx-vulkan",
373 feature = "rafx-gles2",
374 feature = "rafx-gles3"
375 ))
376 ))]
377 #[doc(hidden)]
378 pub empty: Option<RafxShaderModuleDefEmpty<'a>>,
379}