Bug 1562788 - Add support for benchmarking llvmpipe and swiftshader in wrench. r=nical
☠☠ backed out by 58fa32c56ff0 ☠ ☠
authorGlenn Watson <github@intuitionlibrary.com>
Tue, 02 Jul 2019 17:15:18 +0000
changeset 543858 9c6775d713e80c531dcbec5d7985021eeebd251e
parent 543857 a248baf9930163ebeb066239174ed57b9bbb0b06
child 543859 531e69180f15e79c2449e747c0204b83e3a1aee7
push id2131
push userffxbld-merge
push dateMon, 26 Aug 2019 18:30:20 +0000
treeherdermozilla-release@b19ffb3ca153 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersnical
bugs1562788
milestone69.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1562788 - Add support for benchmarking llvmpipe and swiftshader in wrench. r=nical * Add a script for running wrench under various software rasterizers. * Add support to wrench for non-blocking event loop. * Add support to wrench for selecting GL/ES rendering API. * Update x11 bindings for wrench, to fix a release only crash. Differential Revision: https://phabricator.services.mozilla.com/D36551
gfx/wr/Cargo.lock
gfx/wr/wrench/script/wrench_with_renderer.py
gfx/wr/wrench/src/args.yaml
gfx/wr/wrench/src/main.rs
--- a/gfx/wr/Cargo.lock
+++ b/gfx/wr/Cargo.lock
@@ -599,17 +599,17 @@ dependencies = [
  "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
  "objc 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "osmesa-sys 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "shared_library 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "wayland-client 0.20.10 (registry+https://github.com/rust-lang/crates.io-index)",
  "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "winit 0.16.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "x11-dl 2.17.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "x11-dl 2.18.3 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "half"
 version = "1.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
@@ -1893,17 +1893,17 @@ dependencies = [
  "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "objc 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "parking_lot 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "smithay-client-toolkit 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "wayland-client 0.20.10 (registry+https://github.com/rust-lang/crates.io-index)",
  "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
- "x11-dl 2.17.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "x11-dl 2.18.3 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "wr_malloc_size_of"
 version = "0.0.1"
 dependencies = [
  "app_units 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "euclid 0.19.5 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1966,17 +1966,17 @@ version = "0.2.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "x11-dl"
-version = "2.17.5"
+version = "2.18.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
  "pkg-config 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -2216,13 +2216,13 @@ dependencies = [
 "checksum winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "92c1eb33641e276cfa214a0522acad57be5c56b10cb348b3c5117db75f3ac4b0"
 "checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc"
 "checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
 "checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
 "checksum wincolor 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "eeb06499a3a4d44302791052df005d5232b927ed1a9658146d842165c4de7767"
 "checksum winit 0.16.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ec43db5991cc509f5b0c68cb0a0d3614f697c888999990a186a2e895c7f723c0"
 "checksum ws 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ec91ea61b83ce033c43c06c52ddc7532f465c0153281610d44c58b74083aee1a"
 "checksum ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e"
-"checksum x11-dl 2.17.5 (registry+https://github.com/rust-lang/crates.io-index)" = "3235540540fde1ae074c8df49054166c0e070407f1c6e1ee17b8c87c2c7bcc7d"
+"checksum x11-dl 2.18.3 (registry+https://github.com/rust-lang/crates.io-index)" = "940586acb859ea05c53971ac231685799a7ec1dee66ac0bccc0e6ad96e06b4e3"
 "checksum xml-rs 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3c1cb601d29fe2c2ac60a2b2e5e293994d87a1f6fa9687a31a15270f909be9c2"
 "checksum xml-rs 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "541b12c998c5b56aa2b4e6f18f03664eef9a4fd0a246a55594efae6cc2d964b5"
 "checksum yaml-rust 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e66366e18dc58b46801afbf2ca7661a9f59cc8c5962c29892b6039b4f86fa992"
 "checksum yaml-rust 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "95acf0db5515d07da9965ec0e0ba6cc2d825e2caeb7303b66ca441729801254e"
new file mode 100755
--- /dev/null
+++ b/gfx/wr/wrench/script/wrench_with_renderer.py
@@ -0,0 +1,52 @@
+#!/usr/bin/python
+
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+import os
+import subprocess
+import sys
+
+
+def is_linux():
+    return sys.platform.startswith('linux')
+
+
+if is_linux():
+    requested_renderer = sys.argv[1]
+    renderer = "default"
+
+    if requested_renderer == 'hardware':
+        pass
+    elif requested_renderer == 'llvmpipe':
+        os.environ["LIBGL_ALWAYS_SOFTWARE"] = "1"
+        os.environ["GALLIUM_DRIVER"] = "llvmpipe"
+    elif requested_renderer == 'softpipe':
+        os.environ["LIBGL_ALWAYS_SOFTWARE"] = "1"
+        os.environ["GALLIUM_DRIVER"] = "softpipe"
+    elif requested_renderer == 'swiftshader':
+        # TODO: Set up LD_LIBRARY_PATH to SwiftShader libraries automatically.
+        renderer = 'es3'
+    else:
+        print('Unknown renderer ' + requested_renderer)
+        sys.exit(1)
+
+    cmd = [
+        'cargo',
+        'run',
+        '--release',
+        '--',
+        '--no-block',               # Run as fast as possible, for benchmarking
+        '--no-picture-caching',     # Disable picture caching, to test rasterization performance
+        '--no-subpixel-aa',         # SwiftShader doesn't support dual source blending, disable subpixel AA for fairer comparisons
+        '--renderer',               # Select GL3/ES3 renderer API
+        renderer,
+        'load'
+    ]
+
+    cmd += sys.argv[2:]
+    print('Running: ' + ' '.join(cmd))
+    subprocess.check_call(cmd)
+else:
+    print('This script is only supported on Linux')
--- a/gfx/wr/wrench/src/args.yaml
+++ b/gfx/wr/wrench/src/args.yaml
@@ -74,16 +74,24 @@ args:
       long: chase
       help: Chase a particular primitive matching the local rect
       takes_value: true
   - dump_shader_source:
       long: dump-shader-source
       help: Dump the source of the specified shader
       takes_value: true
       global: true
+  - renderer:
+      long: renderer
+      help: Select rendering API (gl3, es3)
+      takes_value: true
+      global: true
+  - no_block:
+      long: no-block
+      help: Don't block on UI events - run event loop as fast as possible.
 
 subcommands:
     - png:
         about: render frame described by YAML and save it to a png file
         args:
           - surface:
               short: s
               long: surface
--- a/gfx/wr/wrench/src/main.rs
+++ b/gfx/wr/wrench/src/main.rs
@@ -241,24 +241,22 @@ impl WindowWrapper {
 }
 
 fn make_window(
     size: DeviceIntSize,
     dp_ratio: Option<f32>,
     vsync: bool,
     events_loop: &Option<winit::EventsLoop>,
     angle: bool,
+    gl_request: glutin::GlRequest,
 ) -> WindowWrapper {
     let wrapper = match *events_loop {
         Some(ref events_loop) => {
             let context_builder = glutin::ContextBuilder::new()
-                .with_gl(glutin::GlRequest::GlThenGles {
-                    opengl_version: (3, 2),
-                    opengles_version: (3, 0),
-                })
+                .with_gl(gl_request)
                 .with_vsync(vsync);
             let window_builder = winit::WindowBuilder::new()
                 .with_title("WRench")
                 .with_multitouch()
                 .with_dimensions(LogicalSize::new(size.width as f64, size.height as f64));
 
             let init = |context: &dyn glutin::GlContext| {
                 unsafe {
@@ -479,18 +477,41 @@ fn main() {
     let dump_shader_source = args.value_of("dump_shader_source").map(String::from);
 
     let mut events_loop = if args.is_present("headless") {
         None
     } else {
         Some(winit::EventsLoop::new())
     };
 
+    let gl_request = match args.value_of("renderer") {
+        Some("es3") => {
+            glutin::GlRequest::Specific(glutin::Api::OpenGlEs, (3, 0))
+        }
+        Some("gl3") => {
+            glutin::GlRequest::Specific(glutin::Api::OpenGl, (3, 2))
+        }
+        Some("default") | None => {
+            glutin::GlRequest::GlThenGles {
+                opengl_version: (3, 2),
+                opengles_version: (3, 0),
+            }
+        }
+        Some(api) => {
+            panic!("Unexpected renderer string {}", api);
+        }
+    };
+
     let mut window = make_window(
-        size, dp_ratio, args.is_present("vsync"), &events_loop, args.is_present("angle"),
+        size,
+        dp_ratio,
+        args.is_present("vsync"),
+        &events_loop,
+        args.is_present("angle"),
+        gl_request,
     );
     let dp_ratio = dp_ratio.unwrap_or(window.hidpi_factor());
     let dim = window.get_inner_size();
 
     let needs_frame_notifier = ["perf", "reftest", "png", "rawtest"]
         .iter()
         .any(|s| args.subcommand_matches(s).is_some());
     let (notifier, rx) = if needs_frame_notifier {
@@ -523,17 +544,25 @@ fn main() {
 
     if let Some(window_title) = wrench.take_title() {
         if !cfg!(windows) {
             window.set_title(&window_title);
         }
     }
 
     if let Some(subargs) = args.subcommand_matches("show") {
-        render(&mut wrench, &mut window, size, &mut events_loop, subargs);
+        let no_block = args.is_present("no_block");
+        render(
+            &mut wrench,
+            &mut window,
+            size,
+            &mut events_loop,
+            subargs,
+            no_block,
+        );
     } else if let Some(subargs) = args.subcommand_matches("png") {
         let surface = match subargs.value_of("surface") {
             Some("screen") | None => png::ReadSurface::Screen,
             Some("gpu-cache") => png::ReadSurface::GpuCache,
             _ => panic!("Unknown surface argument value")
         };
         let output_path = subargs.value_of("OUTPUT").map(|s| PathBuf::from(s));
         let reader = YamlFrameReader::new_from_args(subargs);
@@ -566,16 +595,17 @@ fn main() {
 }
 
 fn render<'a>(
     wrench: &mut Wrench,
     window: &mut WindowWrapper,
     size: DeviceIntSize,
     events_loop: &mut Option<winit::EventsLoop>,
     subargs: &clap::ArgMatches<'a>,
+    no_block: bool,
 ) {
     let input_path = subargs.value_of("INPUT").map(PathBuf::from).unwrap();
 
     // If the input is a directory, we are looking at a capture.
     let mut thing = if input_path.as_path().is_dir() {
         let mut documents = wrench.api.load_capture(input_path);
         println!("loaded {:?}", documents.iter().map(|cd| cd.document_id).collect::<Vec<_>>());
         let captured = documents.swap_remove(0);
@@ -830,17 +860,17 @@ fn render<'a>(
             // (a) Block the thread when no events are present (for CPU/battery purposes)
             // (b) Don't lag the input events by having the event queue back up.
             loop {
                 let mut pending_events = Vec::new();
 
                 // Block the thread until at least one event arrives
                 // On Android, we are generally profiling when running
                 // wrench, and don't want to block on UI events.
-                if cfg!(not(target_os = "android")) {
+                if !no_block && cfg!(not(target_os = "android")) {
                     events_loop.run_forever(|event| {
                         pending_events.push(event);
                         winit::ControlFlow::Break
                     });
                 }
 
                 // Collect any other pending events that are also available
                 events_loop.poll_events(|event| {