aboutsummaryrefslogtreecommitdiff
path: root/stockton-skeleton/src/draw_passes/cons.rs
blob: 9fb5d5db6ddf5f2f99191f6157db456340bb1bf4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
//! Code for using multiple draw passes in place of just one
//! Note that this can be extended to an arbitrary amount of draw passes.

use super::{Beginning, DrawPass, End, IntoDrawPass, Middle, Singular};
use crate::{
    context::RenderingContext, queue_negotiator::QueueFamilyNegotiator, session::Session, types::*,
};

use anyhow::Result;

/// One draw pass, then another.
pub struct ConsDrawPass<A, B> {
    pub a: A,
    pub b: B,
}

macro_rules! cons_shared_impl {
    () => {
        fn queue_draw(
            &mut self,
            session: &Session,
            img_view: &ImageViewT,
            cmd_buffer: &mut CommandBufferT,
        ) -> Result<()> {
            self.a.queue_draw(session, img_view, cmd_buffer)?;
            self.b.queue_draw(session, img_view, cmd_buffer)?;

            Ok(())
        }
        fn deactivate(self, context: &mut RenderingContext) -> Result<()> {
            self.a.deactivate(context)?;
            self.b.deactivate(context)
        }

        fn handle_surface_change(
            mut self,
            session: &Session,
            context: &mut RenderingContext,
        ) -> Result<Self> {
            match self.a.handle_surface_change(session, context) {
                Ok(a) => self.a = a,
                Err(e) => {
                    self.b.deactivate(context)?;
                    return Err(e);
                }
            }
            match self.b.handle_surface_change(session, context) {
                Ok(b) => self.b = b,
                Err(e) => {
                    self.a.deactivate(context)?;
                    return Err(e);
                }
            }

            Ok(self)
        }
    };
}

impl<A, B> DrawPass<Singular> for ConsDrawPass<A, B>
where
    A: DrawPass<Beginning>,
    B: DrawPass<End>,
{
    cons_shared_impl! {}
}

impl<A, B> DrawPass<End> for ConsDrawPass<A, B>
where
    A: DrawPass<Middle>,
    B: DrawPass<End>,
{
    cons_shared_impl! {}
}

macro_rules! into_shared_impl {
    () => {
        fn init(
            self,
            session: &mut Session,
            context: &mut RenderingContext,
        ) -> Result<ConsDrawPass<A, B>> {
            Ok(ConsDrawPass {
                a: self.0.init(session, context)?,
                b: self.1.init(session, context)?,
            })
        }

        fn find_aux_queues<'a>(
            adapter: &'a Adapter,
            queue_negotiator: &mut QueueFamilyNegotiator,
        ) -> Result<()> {
            IA::find_aux_queues(adapter, queue_negotiator)?;
            IB::find_aux_queues(adapter, queue_negotiator)?;
            Ok(())
        }
    };
}

impl<A, B, IA, IB> IntoDrawPass<ConsDrawPass<A, B>, Singular> for (IA, IB)
where
    A: DrawPass<Beginning>,
    B: DrawPass<End>,
    IA: IntoDrawPass<A, Beginning>,
    IB: IntoDrawPass<B, End>,
{
    into_shared_impl! {}
}

impl<A, B, IA, IB> IntoDrawPass<ConsDrawPass<A, B>, End> for (IA, IB)
where
    A: DrawPass<Middle>,
    B: DrawPass<End>,
    IA: IntoDrawPass<A, Middle>,
    IB: IntoDrawPass<B, End>,
{
    into_shared_impl! {}
}