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
use program::raw::RawProgram;


const MASK_HAS_TESS_EVAL: u8 = 0b00000001;
const MASK_HAS_TESS_CONTROL: u8 = 0b00000010;
const MASK_HAS_GEOMETRY: u8 = 0b00000100;

/// Glium attaches internal information to a binary to be able to fully restore the program.
pub fn attach_glium_header(raw: &RawProgram, data: &mut Vec<u8>) {
    let mut header_byte = 0u8;
    if raw.has_tessellation_evaluation_shader() {
        header_byte = header_byte ^ MASK_HAS_TESS_EVAL;
    }
    if raw.has_tessellation_control_shader() {
        header_byte = header_byte ^ MASK_HAS_TESS_CONTROL;
    }
    if raw.has_geometry_shader() {
        header_byte = header_byte ^ MASK_HAS_GEOMETRY;
    }
    // TODO kind of inefficient.
    data.reserve(1);
    data.insert(0, header_byte);
}

/// Reads the first byte of the data (=glium header) and returns the corresponding shader flags.
/// If the header is not valid, returns None.
pub fn process_glium_header(data: &[u8]) -> Option<(bool, bool, bool)> {
    let header_byte = data[0];
    if header_byte >> 3 == 0 {
        let has_geometry_shader =                (header_byte & MASK_HAS_GEOMETRY) != 0;
        let has_tessellation_control_shader =    (header_byte & MASK_HAS_TESS_CONTROL) != 0;
        let has_tessellation_evaluation_shader = (header_byte & MASK_HAS_TESS_EVAL) != 0;
        Some((has_geometry_shader, has_tessellation_control_shader, has_tessellation_evaluation_shader))
    } else {
        None
    }
}