1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4
5 extern crate mozangle;
6 extern crate webrender;
7
8 use mozangle::shaders::{BuiltInResources, Output, ShaderSpec, ShaderValidator};
9
10 // from glslang
11 const FRAGMENT_SHADER: u32 = 0x8B30;
12 const VERTEX_SHADER: u32 = 0x8B31;
13
14 struct Shader {
15 name: &'static str,
16 features: &'static [&'static str],
17 }
18
19 const SHADER_PREFIX: &str = "#define WR_MAX_VERTEX_TEXTURE_WIDTH 1024\n";
20
21 const CLIP_FEATURES: &[&str] = &["TRANSFORM"];
22 const CACHE_FEATURES: &[&str] = &[""];
23 const PRIM_FEATURES: &[&str] = &["", "TRANSFORM"];
24
25 const SHADERS: &[Shader] = &[
26 // Clip mask shaders
27 Shader {
28 name: "cs_clip_rectangle",
29 features: CLIP_FEATURES,
30 },
31 Shader {
32 name: "cs_clip_image",
33 features: CLIP_FEATURES,
34 },
35 Shader {
36 name: "cs_clip_box_shadow",
37 features: CLIP_FEATURES,
38 },
39 Shader {
40 name: "cs_clip_border",
41 features: CLIP_FEATURES,
42 },
43 // Cache shaders
44 Shader {
45 name: "cs_blur",
46 features: CACHE_FEATURES,
47 },
48 Shader {
49 name: "cs_text_run",
50 features: CACHE_FEATURES,
51 },
52 // Prim shaders
53 Shader {
54 name: "ps_border_corner",
55 features: PRIM_FEATURES,
56 },
57 Shader {
58 name: "ps_border_edge",
59 features: PRIM_FEATURES,
60 },
61 Shader {
62 name: "ps_hardware_composite",
63 features: PRIM_FEATURES,
64 },
65 Shader {
66 name: "ps_split_composite",
67 features: PRIM_FEATURES,
68 },
69 Shader {
70 name: "ps_image",
71 features: PRIM_FEATURES,
72 },
73 Shader {
74 name: "ps_text_run",
75 features: PRIM_FEATURES,
76 },
77 // Brush shaders
78 Shader {
79 name: "brush_yuv_image",
80 features: &["", "YUV_NV12", "YUV_PLANAR", "YUV_INTERLEAVED", "YUV_NV12,TEXTURE_RECT"],
81 },
82 Shader {
83 name: "brush_mask",
84 features: &[],
85 },
86 Shader {
87 name: "brush_solid",
88 features: &[],
89 },
90 Shader {
91 name: "brush_blend",
92 features: &[],
93 },
94 Shader {
95 name: "brush_composite",
96 features: &[],
97 },
98 Shader {
99 name: "brush_line",
100 features: &[],
101 },
102 Shader {
103 name: "brush_radial_gradient",
104 features: &[ "DITHERING" ],
105 },
106 Shader {
107 name: "brush_linear_gradient",
108 features: &[],
109 },
110 ];
111
112 const VERSION_STRING: &str = "#version 300 es\n";
113
114 #[test]
validate_shaders()115 fn validate_shaders() {
116 mozangle::shaders::initialize().unwrap();
117
118 let resources = BuiltInResources::default();
119 let vs_validator =
120 ShaderValidator::new(VERTEX_SHADER, ShaderSpec::Gles3, Output::Essl, &resources).unwrap();
121
122 let fs_validator =
123 ShaderValidator::new(FRAGMENT_SHADER, ShaderSpec::Gles3, Output::Essl, &resources).unwrap();
124
125 for shader in SHADERS {
126 for config in shader.features {
127 let mut features = String::new();
128 features.push_str(SHADER_PREFIX);
129
130 for feature in config.split(",") {
131 features.push_str(&format!("#define WR_FEATURE_{}", feature));
132 }
133
134 let (vs, fs) =
135 webrender::build_shader_strings(VERSION_STRING, &features, shader.name, &None);
136
137 validate(&vs_validator, shader.name, vs);
138 validate(&fs_validator, shader.name, fs);
139 }
140 }
141 }
142
validate(validator: &ShaderValidator, name: &str, source: String)143 fn validate(validator: &ShaderValidator, name: &str, source: String) {
144 // Check for each `switch` to have a `default`, see
145 // https://github.com/servo/webrender/wiki/Driver-issues#lack-of-default-case-in-a-switch
146 assert_eq!(source.matches("switch").count(), source.matches("default:").count(),
147 "Shader '{}' doesn't have all `switch` covered with `default` cases", name);
148 // Run Angle validator
149 match validator.compile_and_translate(&[&source]) {
150 Ok(_) => {
151 println!("Shader translated succesfully: {}", name);
152 }
153 Err(_) => {
154 panic!(
155 "Shader compilation failed: {}\n{}",
156 name,
157 validator.info_log()
158 );
159 }
160 }
161 }
162