1use super::*;
2use crate::{RafxRootSignature, RafxSampler, RafxShader, RafxShaderModule};
3use rafx_base::DecimalF32;
4use std::hash::{Hash, Hasher};
5
6use fnv::FnvHasher;
7#[cfg(feature = "serde-support")]
8use serde::{Deserialize, Serialize};
9
10#[derive(Default)]
12pub struct RafxApiDef {
13 #[cfg(feature = "rafx-dx12")]
15 pub dx12_options: Option<crate::RafxApiDefDx12>,
16 #[cfg(feature = "rafx-metal")]
17 pub metal_options: Option<crate::RafxApiDefMetal>,
18 #[cfg(feature = "rafx-vulkan")]
19 pub vk_options: Option<crate::RafxApiDefVulkan>,
20 #[cfg(feature = "rafx-gles2")]
21 pub gles2_options: Option<crate::RafxApiDefGles2>,
22 #[cfg(feature = "rafx-gles3")]
23 pub gles3_options: Option<crate::RafxApiDefGles3>,
24}
25
26#[derive(Clone, Debug, Default)]
27pub struct RafxBufferElementData {
28 pub element_begin_index: u64,
30 pub element_count: u64,
31 pub element_stride: u64,
32}
33
34#[derive(Clone, Debug)]
36pub struct RafxBufferDef {
37 pub size: u64,
38 pub alignment: u32, pub memory_usage: RafxMemoryUsage,
40 pub queue_type: RafxQueueType,
41 pub resource_type: RafxResourceType,
42 pub always_mapped: bool,
43
44 pub format: RafxFormat,
46
47 pub elements: RafxBufferElementData,
49}
50
51impl Default for RafxBufferDef {
52 fn default() -> Self {
53 RafxBufferDef {
54 size: 0,
55 alignment: 0,
56 memory_usage: RafxMemoryUsage::Unknown,
57 queue_type: RafxQueueType::Graphics,
58 resource_type: RafxResourceType::UNDEFINED,
59 elements: Default::default(),
60 format: RafxFormat::UNDEFINED,
61 always_mapped: false,
62 }
63 }
64}
65
66impl RafxBufferDef {
67 pub fn verify(&self) {
68 assert_ne!(self.size, 0);
69 }
70
71 pub fn for_staging_buffer(
72 size: usize,
73 resource_type: RafxResourceType,
74 ) -> RafxBufferDef {
75 RafxBufferDef {
76 size: size as u64,
77 alignment: 0,
78 memory_usage: RafxMemoryUsage::CpuToGpu,
79 queue_type: RafxQueueType::Graphics,
80 resource_type,
81 elements: Default::default(),
82 format: RafxFormat::UNDEFINED,
83 always_mapped: false,
84 }
85 }
86
87 pub fn for_staging_buffer_data<T: Copy>(
88 data: &[T],
89 resource_type: RafxResourceType,
90 ) -> RafxBufferDef {
91 Self::for_staging_buffer(rafx_base::memory::slice_size_in_bytes(data), resource_type)
92 }
93
94 pub fn for_staging_vertex_buffer(size: usize) -> RafxBufferDef {
95 Self::for_staging_buffer(size, RafxResourceType::VERTEX_BUFFER)
96 }
97
98 pub fn for_staging_vertex_buffer_data<T: Copy>(data: &[T]) -> RafxBufferDef {
99 Self::for_staging_buffer_data(data, RafxResourceType::VERTEX_BUFFER)
100 }
101
102 pub fn for_staging_index_buffer(size: usize) -> RafxBufferDef {
103 Self::for_staging_buffer(size, RafxResourceType::INDEX_BUFFER)
104 }
105
106 pub fn for_staging_index_buffer_data<T: Copy>(data: &[T]) -> RafxBufferDef {
107 Self::for_staging_buffer_data(data, RafxResourceType::INDEX_BUFFER)
108 }
109
110 pub fn for_staging_uniform_buffer(size: usize) -> RafxBufferDef {
111 Self::for_staging_buffer(size, RafxResourceType::UNIFORM_BUFFER)
112 }
113
114 pub fn for_staging_uniform_buffer_data<T: Copy>(data: &[T]) -> RafxBufferDef {
115 Self::for_staging_buffer_data(data, RafxResourceType::UNIFORM_BUFFER)
116 }
117}
118
119#[derive(Copy, Clone, Debug, PartialEq)]
121pub enum RafxTextureDimensions {
122 Auto,
124 Dim1D,
125 Dim2D,
126 Dim3D,
127}
128
129impl Default for RafxTextureDimensions {
130 fn default() -> Self {
131 RafxTextureDimensions::Auto
132 }
133}
134
135impl RafxTextureDimensions {
136 pub fn determine_dimensions(
137 self,
138 extents: RafxExtents3D,
139 ) -> RafxTextureDimensions {
140 match self {
141 RafxTextureDimensions::Auto => {
142 if extents.depth > 1 {
143 RafxTextureDimensions::Dim3D
144 } else {
145 RafxTextureDimensions::Dim2D
146 }
147 }
148 RafxTextureDimensions::Dim1D => {
149 assert_eq!(extents.height, 1);
150 assert_eq!(extents.depth, 1);
151 RafxTextureDimensions::Dim1D
152 }
153 RafxTextureDimensions::Dim2D => {
154 assert_eq!(extents.depth, 1);
155 RafxTextureDimensions::Dim2D
156 }
157 RafxTextureDimensions::Dim3D => RafxTextureDimensions::Dim3D,
158 }
159 }
160}
161
162#[derive(Clone, Debug)]
164pub struct RafxTextureDef {
165 pub extents: RafxExtents3D,
166 pub array_length: u32,
169 pub mip_count: u32,
170 pub sample_count: RafxSampleCount,
171 pub format: RafxFormat,
172 pub resource_type: RafxResourceType,
173 pub dimensions: RafxTextureDimensions,
176}
177
178impl Default for RafxTextureDef {
179 fn default() -> Self {
180 RafxTextureDef {
181 extents: RafxExtents3D {
182 width: 0,
183 height: 0,
184 depth: 0,
185 },
186 array_length: 1,
187 mip_count: 1,
188 sample_count: RafxSampleCount::SampleCount1,
189 format: RafxFormat::UNDEFINED,
190 resource_type: RafxResourceType::TEXTURE,
191 dimensions: RafxTextureDimensions::Auto,
192 }
193 }
194}
195
196impl RafxTextureDef {
197 pub fn verify(&self) {
198 assert!(self.extents.width > 0);
199 assert!(self.extents.height > 0);
200 assert!(self.extents.depth > 0);
201 assert!(self.array_length > 0);
202 assert!(self.mip_count > 0);
203 assert!(self.mip_count < 2 || self.sample_count == RafxSampleCount::SampleCount1);
204
205 if self.resource_type.contains(RafxResourceType::TEXTURE_CUBE) {
206 assert_eq!(self.array_length % 6, 0);
207 }
208
209 assert!(
211 !(self.resource_type.contains(
212 RafxResourceType::RENDER_TARGET_ARRAY_SLICES
213 | RafxResourceType::RENDER_TARGET_DEPTH_SLICES
214 ))
215 );
216
217 assert!(
218 !(self.format.has_depth()
219 && self
220 .resource_type
221 .intersects(RafxResourceType::TEXTURE_READ_WRITE)),
222 "Cannot use depth stencil as UAV"
223 );
224 }
225}
226
227#[derive(Debug, Clone, PartialEq, Eq, Hash)]
229pub struct RafxCommandPoolDef {
230 pub transient: bool,
233}
234
235#[derive(Debug, Clone, PartialEq)]
237pub struct RafxCommandBufferDef {
238 pub is_secondary: bool,
240}
241
242#[derive(Clone, Debug)]
244pub struct RafxSwapchainDef {
245 pub width: u32,
246 pub height: u32,
247 pub enable_vsync: bool,
248 pub color_space_priority: Vec<RafxSwapchainColorSpace>,
249 }
251
252#[derive(Clone, Debug)]
254pub struct RafxShaderStageDef {
255 pub shader_module: RafxShaderModule,
256 pub reflection: RafxShaderStageReflection,
257}
258
259impl RafxShaderStageDef {
260 pub fn hash_definition<HasherT: std::hash::Hasher, ShaderModuleHashT: Hash>(
261 hasher: &mut HasherT,
262 reflection_data: &[&RafxShaderStageReflection],
263 shader_module_hashes: &[ShaderModuleHashT],
264 ) {
265 assert_eq!(reflection_data.len(), shader_module_hashes.len());
266 fn hash_stage<HasherT: std::hash::Hasher, ShaderModuleHashT: Hash>(
267 hasher: &mut HasherT,
268 stage_flag: RafxShaderStageFlags,
269 reflection_data: &[&RafxShaderStageReflection],
270 shader_module_hashes: &[ShaderModuleHashT],
271 ) {
272 for (reflection, shader_module_hash) in reflection_data.iter().zip(shader_module_hashes)
273 {
274 if reflection.shader_stage.intersects(stage_flag) {
275 reflection.shader_stage.hash(hasher);
276 reflection.entry_point_name.hash(hasher);
277 reflection.resources.hash(hasher);
278 shader_module_hash.hash(hasher);
279 break;
280 }
281 }
282 }
283
284 for stage_flag in &crate::ALL_SHADER_STAGE_FLAGS {
286 hash_stage(hasher, *stage_flag, reflection_data, shader_module_hashes);
287 }
288 }
289}
290
291#[derive(Clone, Hash, Debug)]
293pub enum RafxImmutableSamplerKey<'a> {
294 Name(&'a str),
295 Binding(u32, u32),
296}
297
298impl<'a> RafxImmutableSamplerKey<'a> {
299 pub fn from_name(name: &'a str) -> RafxImmutableSamplerKey<'a> {
300 RafxImmutableSamplerKey::Name(name)
301 }
302
303 pub fn from_binding(
304 set_index: u32,
305 binding: u32,
306 ) -> RafxImmutableSamplerKey<'a> {
307 RafxImmutableSamplerKey::Binding(set_index, binding)
308 }
309}
310
311#[derive(Debug)]
313pub struct RafxImmutableSamplers<'a> {
314 pub key: RafxImmutableSamplerKey<'a>,
315 pub samplers: &'a [RafxSampler],
316}
317
318impl<'a> RafxImmutableSamplers<'a> {
319 pub fn from_name(
320 name: &'a str,
321 samplers: &'a [RafxSampler],
322 ) -> RafxImmutableSamplers<'a> {
323 RafxImmutableSamplers {
324 key: RafxImmutableSamplerKey::from_name(name),
325 samplers,
326 }
327 }
328
329 pub fn from_binding(
330 set_index: u32,
331 binding: u32,
332 samplers: &'a [RafxSampler],
333 ) -> RafxImmutableSamplers<'a> {
334 RafxImmutableSamplers {
335 key: RafxImmutableSamplerKey::from_binding(set_index, binding),
336 samplers,
337 }
338 }
339}
340
341pub struct RafxRootSignatureDef<'a> {
343 pub shaders: &'a [RafxShader],
344 pub immutable_samplers: &'a [RafxImmutableSamplers<'a>],
345}
346
347impl<'a> RafxRootSignatureDef<'a> {
348 pub fn hash_definition<
351 HasherT: std::hash::Hasher,
352 ShaderHashT: Hash,
353 ImmutableSamplerHashT: Hash,
354 >(
355 hasher: &mut HasherT,
356 shader_hashes: &[ShaderHashT],
357 immutable_sampler_keys: &[RafxImmutableSamplerKey],
358 immutable_sampler_hashes: &[Vec<ImmutableSamplerHashT>],
359 ) {
360 let mut combined_shaders_hash = 0;
362 for shader_hash in shader_hashes {
363 let mut h = FnvHasher::default();
364 shader_hash.hash(&mut h);
365 combined_shaders_hash ^= h.finish();
366 }
367
368 let mut combined_immutable_samplers_hash = 0;
371 for (key, samplers) in immutable_sampler_keys.iter().zip(immutable_sampler_hashes) {
372 let mut h = FnvHasher::default();
373 key.hash(&mut h);
374 samplers.hash(&mut h);
375 combined_immutable_samplers_hash ^= h.finish();
376 }
377
378 combined_shaders_hash.hash(hasher);
380 combined_immutable_samplers_hash.hash(hasher);
381 }
382}
383
384#[derive(Debug, Clone, PartialEq, Default)]
386#[cfg_attr(feature = "serde-support", derive(Serialize, Deserialize))]
387pub struct RafxSamplerDef {
388 #[cfg_attr(feature = "serde-support", serde(default))]
389 pub min_filter: RafxFilterType,
390 #[cfg_attr(feature = "serde-support", serde(default))]
391 pub mag_filter: RafxFilterType,
392 #[cfg_attr(feature = "serde-support", serde(default))]
393 pub mip_map_mode: RafxMipMapMode,
394 #[cfg_attr(feature = "serde-support", serde(default))]
395 pub address_mode_u: RafxAddressMode,
396 #[cfg_attr(feature = "serde-support", serde(default))]
397 pub address_mode_v: RafxAddressMode,
398 #[cfg_attr(feature = "serde-support", serde(default))]
399 pub address_mode_w: RafxAddressMode,
400 #[cfg_attr(feature = "serde-support", serde(default))]
401 pub mip_lod_bias: f32,
402 #[cfg_attr(feature = "serde-support", serde(default))]
403 pub max_anisotropy: f32,
404 #[cfg_attr(feature = "serde-support", serde(default))]
405 pub compare_op: RafxCompareOp,
406 }
408
409impl Eq for RafxSamplerDef {}
410
411impl Hash for RafxSamplerDef {
412 fn hash<H: Hasher>(
413 &self,
414 mut state: &mut H,
415 ) {
416 self.min_filter.hash(&mut state);
417 self.mag_filter.hash(&mut state);
418 self.mip_map_mode.hash(&mut state);
419 self.address_mode_u.hash(&mut state);
420 self.address_mode_v.hash(&mut state);
421 self.address_mode_w.hash(&mut state);
422 DecimalF32(self.mip_lod_bias).hash(&mut state);
423 DecimalF32(self.max_anisotropy).hash(&mut state);
424 self.compare_op.hash(&mut state);
425 }
426}
427
428#[derive(Debug, Clone, PartialEq, Eq, Hash)]
430pub struct RafxVertexLayoutAttribute {
431 pub format: RafxFormat,
433 pub buffer_index: u32,
435 pub location: u32,
437 pub byte_offset: u32,
439
440 pub hlsl_semantic: String,
442 pub gl_attribute_name: Option<String>,
444}
445
446#[derive(Debug, Clone, PartialEq, Eq, Hash)]
448pub struct RafxVertexLayoutBuffer {
449 pub stride: u32,
450 pub rate: RafxVertexAttributeRate,
451}
452
453#[derive(Debug, Clone, PartialEq, Eq, Hash)]
455pub struct RafxVertexLayout {
456 pub attributes: Vec<RafxVertexLayoutAttribute>,
457 pub buffers: Vec<RafxVertexLayoutBuffer>,
458}
459
460#[derive(Debug, Clone, PartialEq, Eq, Hash)]
462#[cfg_attr(feature = "serde-support", derive(Serialize, Deserialize))]
463pub struct RafxDepthState {
464 pub depth_test_enable: bool,
465 pub depth_write_enable: bool,
466 pub depth_compare_op: RafxCompareOp,
467 pub stencil_test_enable: bool,
468 pub stencil_read_mask: u8,
469 pub stencil_write_mask: u8,
470 pub front_depth_fail_op: RafxStencilOp,
471 pub front_stencil_compare_op: RafxCompareOp,
472 pub front_stencil_fail_op: RafxStencilOp,
473 pub front_stencil_pass_op: RafxStencilOp,
474 pub back_depth_fail_op: RafxStencilOp,
475 pub back_stencil_compare_op: RafxCompareOp,
476 pub back_stencil_fail_op: RafxStencilOp,
477 pub back_stencil_pass_op: RafxStencilOp,
478}
479
480impl Default for RafxDepthState {
481 fn default() -> Self {
482 RafxDepthState {
483 depth_test_enable: false,
484 depth_write_enable: false,
485 depth_compare_op: RafxCompareOp::Always,
486 stencil_test_enable: false,
487 stencil_read_mask: 0xFF,
488 stencil_write_mask: 0xFF,
489 front_depth_fail_op: Default::default(),
490 front_stencil_compare_op: RafxCompareOp::Always,
491 front_stencil_fail_op: Default::default(),
492 front_stencil_pass_op: Default::default(),
493 back_depth_fail_op: Default::default(),
494 back_stencil_compare_op: RafxCompareOp::Always,
495 back_stencil_fail_op: Default::default(),
496 back_stencil_pass_op: Default::default(),
497 }
498 }
499}
500
501#[derive(Debug, Clone, PartialEq)]
503#[cfg_attr(feature = "serde-support", derive(Serialize, Deserialize))]
504pub struct RafxRasterizerState {
505 pub cull_mode: RafxCullMode,
506 pub front_face: RafxFrontFace,
507 pub fill_mode: RafxFillMode,
508 pub depth_bias: i32,
509 pub depth_bias_slope_scaled: f32,
510 pub depth_clamp_enable: bool,
511 pub multisample: bool,
512 pub scissor: bool,
513 }
515
516impl Eq for RafxRasterizerState {}
517
518impl Hash for RafxRasterizerState {
519 fn hash<H: Hasher>(
520 &self,
521 mut state: &mut H,
522 ) {
523 self.cull_mode.hash(&mut state);
524 self.front_face.hash(&mut state);
525 self.fill_mode.hash(&mut state);
526 self.depth_bias.hash(&mut state);
527 DecimalF32(self.depth_bias_slope_scaled).hash(&mut state);
528 self.depth_clamp_enable.hash(&mut state);
529 self.multisample.hash(&mut state);
530 self.scissor.hash(&mut state);
531 }
532}
533
534impl Default for RafxRasterizerState {
535 fn default() -> Self {
536 RafxRasterizerState {
537 cull_mode: RafxCullMode::None,
538 front_face: Default::default(),
539 fill_mode: Default::default(),
540 depth_bias: 0,
541 depth_bias_slope_scaled: 0.0,
542 depth_clamp_enable: false,
543 multisample: false,
544 scissor: false,
545 }
546 }
547}
548
549#[derive(Debug, Clone, PartialEq, Eq, Hash)]
551#[cfg_attr(feature = "serde-support", derive(Serialize, Deserialize))]
552pub struct RafxBlendStateRenderTarget {
553 pub src_factor: RafxBlendFactor,
554 pub dst_factor: RafxBlendFactor,
555 pub src_factor_alpha: RafxBlendFactor,
556 pub dst_factor_alpha: RafxBlendFactor,
557 pub blend_op: RafxBlendOp,
558 pub blend_op_alpha: RafxBlendOp,
559 pub masks: RafxColorFlags,
560}
561
562impl Default for RafxBlendStateRenderTarget {
563 fn default() -> Self {
564 RafxBlendStateRenderTarget {
565 blend_op: RafxBlendOp::Add,
566 blend_op_alpha: RafxBlendOp::Add,
567 src_factor: RafxBlendFactor::One,
568 src_factor_alpha: RafxBlendFactor::One,
569 dst_factor: RafxBlendFactor::Zero,
570 dst_factor_alpha: RafxBlendFactor::Zero,
571 masks: RafxColorFlags::ALL,
572 }
573 }
574}
575
576impl RafxBlendStateRenderTarget {
577 pub fn default_alpha_disabled() -> Self {
578 Default::default()
579 }
580
581 pub fn default_alpha_enabled() -> Self {
582 RafxBlendStateRenderTarget {
583 src_factor: RafxBlendFactor::SrcAlpha,
584 dst_factor: RafxBlendFactor::OneMinusSrcAlpha,
585 src_factor_alpha: RafxBlendFactor::Zero,
586 dst_factor_alpha: RafxBlendFactor::One,
587 blend_op: RafxBlendOp::Add,
588 blend_op_alpha: RafxBlendOp::Add,
589 masks: RafxColorFlags::ALL,
590 }
591 }
592}
593
594impl RafxBlendStateRenderTarget {
595 pub fn blend_enabled(&self) -> bool {
596 self.src_factor != RafxBlendFactor::One
597 || self.src_factor_alpha != RafxBlendFactor::One
598 || self.dst_factor != RafxBlendFactor::Zero
599 || self.dst_factor_alpha != RafxBlendFactor::Zero
600 }
601}
602
603#[derive(Debug, Clone, PartialEq, Eq, Hash)]
606#[cfg_attr(feature = "serde-support", derive(Serialize, Deserialize))]
607pub struct RafxBlendState {
608 pub render_target_blend_states: Vec<RafxBlendStateRenderTarget>,
610
611 pub render_target_mask: RafxBlendStateTargets,
614
615 pub independent_blend: bool,
619}
620
621impl RafxBlendState {
622 pub fn default_alpha_disabled() -> Self {
623 RafxBlendState {
624 render_target_blend_states: vec![RafxBlendStateRenderTarget::default_alpha_disabled()],
625 render_target_mask: RafxBlendStateTargets::BLEND_STATE_TARGET_ALL,
626 independent_blend: false,
627 }
628 }
629
630 pub fn default_alpha_enabled() -> Self {
631 RafxBlendState {
632 render_target_blend_states: vec![RafxBlendStateRenderTarget::default_alpha_enabled()],
633 render_target_mask: RafxBlendStateTargets::BLEND_STATE_TARGET_ALL,
634 independent_blend: false,
635 }
636 }
637}
638
639impl Default for RafxBlendState {
640 fn default() -> Self {
641 Self::default_alpha_disabled()
642 }
643}
644
645impl RafxBlendState {
646 pub fn verify(
647 &self,
648 color_attachment_count: usize,
649 ) {
650 if !self.independent_blend {
651 assert_eq!(self.render_target_blend_states.len(), 1, "If RafxBlendState::independent_blend is false, RafxBlendState::render_target_blend_states must be 1");
652 } else {
653 assert_eq!(self.render_target_blend_states.len(), color_attachment_count, "If RafxBlendState::independent_blend is true, RafxBlendState::render_target_blend_states length must match color attachment count");
654 }
655 }
656}
657
658#[derive(Debug)]
660pub struct RafxGraphicsPipelineDef<'a> {
661 pub shader: &'a RafxShader,
662 pub root_signature: &'a RafxRootSignature,
663 pub vertex_layout: &'a RafxVertexLayout,
664 pub blend_state: &'a RafxBlendState,
665 pub depth_state: &'a RafxDepthState,
666 pub rasterizer_state: &'a RafxRasterizerState,
667 pub primitive_topology: RafxPrimitiveTopology,
668 pub color_formats: &'a [RafxFormat],
669 pub depth_stencil_format: Option<RafxFormat>,
670 pub sample_count: RafxSampleCount,
671 pub debug_name: Option<&'a str>,
672}
673
674#[derive(Debug)]
676pub struct RafxComputePipelineDef<'a> {
677 pub shader: &'a RafxShader,
678 pub root_signature: &'a RafxRootSignature,
679 pub debug_name: Option<&'a str>,
680}
681
682pub struct RafxDescriptorSetArrayDef<'a> {
684 pub root_signature: &'a RafxRootSignature,
686 pub set_index: u32,
688 pub array_length: usize,
690}