Browse Source

Support additional lists of validation tests

Popov72 4 years ago
parent
commit
359f5ce577
24 changed files with 198 additions and 36 deletions
  1. BIN
      tests/validation/ReferenceImages/webgpu/apply all post processes.png
  2. BIN
      tests/validation/ReferenceImages/webgpu/blur cube with the effect renderer.png
  3. BIN
      tests/validation/ReferenceImages/webgpu/cube reflection with probe and mirrors.png
  4. BIN
      tests/validation/ReferenceImages/webgpu/cube with holes using stencil buffer.png
  5. BIN
      tests/validation/ReferenceImages/webgpu/default render pipeline.png
  6. BIN
      tests/validation/ReferenceImages/webgpu/edge renderer and zOffset.png
  7. BIN
      tests/validation/ReferenceImages/webgpu/neon pipe with glow layer.png
  8. BIN
      tests/validation/ReferenceImages/webgpu/pillars sphere and torus with PCSS shadows.png
  9. BIN
      tests/validation/ReferenceImages/webgpu/procedural texture with node material.png
  10. BIN
      tests/validation/ReferenceImages/webgpu/show all procedural textures.png
  11. BIN
      tests/validation/ReferenceImages/webgpu/show bounding box.png
  12. BIN
      tests/validation/ReferenceImages/webgpu/show multiple guis.png
  13. BIN
      tests/validation/ReferenceImages/webgpu/simple custom shader.png
  14. BIN
      tests/validation/ReferenceImages/webgpu/simple render target with blue spheres.png
  15. BIN
      tests/validation/ReferenceImages/webgpu/simple sphere in 4 mirrors.png
  16. BIN
      tests/validation/ReferenceImages/webgpu/skybox with boombox.png
  17. BIN
      tests/validation/ReferenceImages/webgpu/soft transparent shadows.png
  18. BIN
      tests/validation/ReferenceImages/webgpu/sphere with custom shader to display wireframe using glow layer.png
  19. BIN
      tests/validation/ReferenceImages/webgpu/torus knot mirror.png
  20. BIN
      tests/validation/ReferenceImages/webgpu/water material.png
  21. 1 1
      tests/validation/index.css
  22. 38 6
      tests/validation/index.html
  23. 63 29
      tests/validation/validation.js
  24. 96 0
      tests/validation/webgpu.json

BIN
tests/validation/ReferenceImages/webgpu/apply all post processes.png


BIN
tests/validation/ReferenceImages/webgpu/blur cube with the effect renderer.png


BIN
tests/validation/ReferenceImages/webgpu/cube reflection with probe and mirrors.png


BIN
tests/validation/ReferenceImages/webgpu/cube with holes using stencil buffer.png


BIN
tests/validation/ReferenceImages/webgpu/default render pipeline.png


BIN
tests/validation/ReferenceImages/webgpu/edge renderer and zOffset.png


BIN
tests/validation/ReferenceImages/webgpu/neon pipe with glow layer.png


BIN
tests/validation/ReferenceImages/webgpu/pillars sphere and torus with PCSS shadows.png


BIN
tests/validation/ReferenceImages/webgpu/procedural texture with node material.png


BIN
tests/validation/ReferenceImages/webgpu/show all procedural textures.png


BIN
tests/validation/ReferenceImages/webgpu/show bounding box.png


BIN
tests/validation/ReferenceImages/webgpu/show multiple guis.png


BIN
tests/validation/ReferenceImages/webgpu/simple custom shader.png


BIN
tests/validation/ReferenceImages/webgpu/simple render target with blue spheres.png


BIN
tests/validation/ReferenceImages/webgpu/simple sphere in 4 mirrors.png


BIN
tests/validation/ReferenceImages/webgpu/skybox with boombox.png


BIN
tests/validation/ReferenceImages/webgpu/soft transparent shadows.png


BIN
tests/validation/ReferenceImages/webgpu/sphere with custom shader to display wireframe using glow layer.png


BIN
tests/validation/ReferenceImages/webgpu/torus knot mirror.png


BIN
tests/validation/ReferenceImages/webgpu/water material.png


+ 1 - 1
tests/validation/index.css

@@ -69,7 +69,7 @@ body {
 
 
 .renderCanvas {
 .renderCanvas {
     position:absolute;
     position:absolute;
-    transform: translateX(-600px);
+    left: -600px;
     width: 600px;
     width: 600px;
     height: 400px;
     height: 400px;
 }
 }

+ 38 - 6
tests/validation/index.html

@@ -11,30 +11,62 @@
 
 
 <body>
 <body>
 	<script>
 	<script>
+        function QueryString() {
+            const idx = window.location.search.indexOf('?');
+
+            if (idx < 0) {
+                return {};
+            }
+
+            const queryString = {},
+                query = window.location.search.substring(idx + 1),
+                vars = query.split("&");
+
+            for (let i = 0; i < vars.length; i++) {
+                const pair = vars[i].split("=");
+                const name = decodeURIComponent(pair[0]);
+                const val = pair.length > 1 ? decodeURIComponent(pair[1]) : null;
+
+                if (val === null) {
+                    queryString["test"] = name;
+                } else if (queryString[name] === undefined) {
+                    queryString[name] = val;
+                } else if (typeof queryString[name] === "string") {
+                    queryString[name] = [ queryString[name], val ];
+                } else {
+                    queryString[name].push(val);
+                }
+            }
+            return queryString;
+        }
+
 		BABYLONDEVTOOLS.Loader.require('validation.js')
 		BABYLONDEVTOOLS.Loader.require('validation.js')
 			.load(function() {
 			.load(function() {
 				// Loading tests
 				// Loading tests
 				var xhr = new XMLHttpRequest();
 				var xhr = new XMLHttpRequest();
 
 
-				xhr.open("GET", "config.json", true);
+                var qs = QueryString();
+
+				xhr.open("GET", qs.list ? qs.list + ".json" : "config.json", true);
 
 
-				xhr.addEventListener("load", function() {
+				xhr.addEventListener("load", async function() {
 					if (xhr.status === 200) {
 					if (xhr.status === 200) {
 
 
 						config = JSON.parse(xhr.responseText);
 						config = JSON.parse(xhr.responseText);
 
 
 						// Run tests
 						// Run tests
 						var index = 0;
 						var index = 0;
-						if (window.location.search) {
+						if (qs.test) {
 							justOnce = true;
 							justOnce = true;
-							var title = window.location.search.replace("?", "").replace(/%20/g, " ");
 							for (var index = 0; index < config.tests.length; index++) {
 							for (var index = 0; index < config.tests.length; index++) {
-								if (config.tests[index].title === title) {
+								if (config.tests[index].title === qs.test) {
 									break;
 									break;
 								}
 								}
 							}
 							}
 						}
 						}
 
 
+                        await init(qs.engine || "webgl2");
+
 						var recursiveRunTest = function(i) {
 						var recursiveRunTest = function(i) {
 							runTest(i, function() {
 							runTest(i, function() {
 								i++;
 								i++;
@@ -42,7 +74,7 @@
 									return;
 									return;
 								}
 								}
 								recursiveRunTest(i);
 								recursiveRunTest(i);
-							});
+							}, qs.list || "");
 						}
 						}
 
 
 						recursiveRunTest(index);
 						recursiveRunTest(index);

+ 63 - 29
tests/validation/validation.js

@@ -46,27 +46,37 @@ function compare(renderData, referenceCanvas, threshold, errorRatio) {
     return (differencesCount * 100) / (width * height) > errorRatio;
     return (differencesCount * 100) / (width * height) > errorRatio;
 }
 }
 
 
-function getRenderData(canvas, engine) {
+async function getRenderData(canvas, engine) {
     var width = canvas.width;
     var width = canvas.width;
     var height = canvas.height;
     var height = canvas.height;
 
 
-    var renderData = engine.readPixels(0, 0, width, height);
-    var numberOfChannelsByLine = width * 4;
-    var halfHeight = height / 2;
-
-    for (var i = 0; i < halfHeight; i++) {
-        for (var j = 0; j < numberOfChannelsByLine; j++) {
-            var currentCell = j + i * numberOfChannelsByLine;
-            var targetLine = height - i - 1;
-            var targetCell = j + targetLine * numberOfChannelsByLine;
-
-            var temp = renderData[currentCell];
-            renderData[currentCell] = renderData[targetCell];
-            renderData[targetCell] = temp;
-        }
-    }
+    return new Promise((resolve) => {
+        engine.onEndFrameObservable.addOnce(async () => {
+            var renderData = await engine.readPixels(0, 0, width, height);
+            var numberOfChannelsByLine = width * 4;
+            var halfHeight = height / 2;
+            for (var i = 0; i < halfHeight; i++) {
+                for (var j = 0; j < numberOfChannelsByLine; j++) {
+                    var currentCell = j + i * numberOfChannelsByLine;
+                    var targetLine = height - i - 1;
+                    var targetCell = j + targetLine * numberOfChannelsByLine;
+
+                    var temp = renderData[currentCell];
+                    renderData[currentCell] = renderData[targetCell];
+                    renderData[targetCell] = temp;
+                }
+            }
+            if (engine.isWebGPU) {
+                for (var i = 0; i < width * height * 4; i += 4) {
+                    var temp = renderData[i + 0];
+                    renderData[i + 0] = renderData[i + 2];
+                    renderData[i + 2] = temp;
+                }
+            }
 
 
-    return renderData;
+            resolve(renderData);
+        });
+    });
 }
 }
 
 
 function saveRenderImage(data, canvas) {
 function saveRenderImage(data, canvas) {
@@ -85,13 +95,13 @@ function saveRenderImage(data, canvas) {
     return screenshotCanvas.toDataURL();
     return screenshotCanvas.toDataURL();
 }
 }
 
 
-function evaluate(test, resultCanvas, result, renderImage, waitRing, done) {
-    var renderData = getRenderData(canvas, engine);
+async function evaluate(test, resultCanvas, result, renderImage, waitRing, done) {
+    var renderData = await getRenderData(canvas, engine);
     var testRes = true;
     var testRes = true;
 
 
     // gl check
     // gl check
     var gl = engine._gl;
     var gl = engine._gl;
-    if (gl.getError() !== 0) {
+    if (gl && gl.getError() !== 0) {
         result.classList.add("failed");
         result.classList.add("failed");
         result.innerHTML = "×";
         result.innerHTML = "×";
         testRes = false;
         testRes = false;
@@ -155,7 +165,7 @@ function processCurrentScene(test, resultCanvas, result, renderImage, index, wai
     });
     });
 }
 }
 
 
-function runTest(index, done) {
+function runTest(index, done, listname) {
     if (index >= config.tests.length) {
     if (index >= config.tests.length) {
         done(false);
         done(false);
     }
     }
@@ -192,7 +202,7 @@ function runTest(index, done) {
 
 
     title.innerHTML = "#" + index + "> " + test.title;
     title.innerHTML = "#" + index + "> " + test.title;
 
 
-    console.log("Running " + test.title);
+    console.log("Running " + (listname ? listname + "/" : "") + test.title);
 
 
     var resultContext = resultCanvas.getContext("2d");
     var resultContext = resultCanvas.getContext("2d");
     var img = new Image();
     var img = new Image();
@@ -354,11 +364,13 @@ function runTest(index, done) {
         }
         }
     }
     }
 
 
-    img.src = "/tests/validation/ReferenceImages/" + test.referenceImage;
+    img.src = "/tests/validation/ReferenceImages/" + (listname ? listname + "/" : "") + (test.referenceImage ? test.referenceImage : test.title + ".png");
 
 
 }
 }
 
 
-function init() {
+function init(engineName) {
+    engineName = engineName.toLowerCase();
+
     BABYLON.SceneLoader.ShowLoadingScreen = false;
     BABYLON.SceneLoader.ShowLoadingScreen = false;
     BABYLON.SceneLoader.ForceFullSceneLoadingForIncremental = true;
     BABYLON.SceneLoader.ForceFullSceneLoadingForIncremental = true;
 
 
@@ -375,9 +387,33 @@ function init() {
     canvas = document.createElement("canvas");
     canvas = document.createElement("canvas");
     canvas.className = "renderCanvas";
     canvas.className = "renderCanvas";
     document.body.appendChild(canvas);
     document.body.appendChild(canvas);
-    engine = new BABYLON.Engine(canvas, false, { useHighPrecisionFloats: true, disableWebGL2Support: window.disableWebGL2Support ? true : false });
-    engine.enableOfflineSupport = false;
-    engine.setDitheringState(false);
+    if (engineName === "webgpu") {
+        const glslangOptions = { 
+            jsPath: "../../dist/preview%20release/glslang/glslang.js",
+            wasmPath: "../../dist/preview%20release/glslang/glslang.wasm"
+        };
+
+        engine = new BABYLON.WebGPUEngine(canvas, {
+            deviceDescriptor: {
+                extensions: [
+                    "texture-compression-bc",
+                    "timestamp-query",
+                    "pipeline-statistics-query",
+                    "depth-clamping",
+                    "depth24unorm-stencil8",
+                    "depth32float-stencil8"
+                ]
+            }
+        });
+        return new Promise((resolve) => {
+            engine.initAsync(glslangOptions).then(() => resolve());
+        });
+    } else {
+        engine = new BABYLON.Engine(canvas, false, { useHighPrecisionFloats: true, disableWebGL2Support: window.disableWebGL2Support || engineName === "webgl" || engineName === "webgl1" ? true : false });
+        engine.enableOfflineSupport = false;
+        engine.setDitheringState(false);
+        return Promise.resolve();
+    }
 }
 }
 
 
 function dispose() {
 function dispose() {
@@ -387,5 +423,3 @@ function dispose() {
     document.body.removeChild(canvas);
     document.body.removeChild(canvas);
     canvas = null;
     canvas = null;
 }
 }
-
-init();

+ 96 - 0
tests/validation/webgpu.json

@@ -0,0 +1,96 @@
+{
+    "root": "https://cdn.babylonjs.com",
+    "tests": [   
+        {
+            "title": "edge renderer and zOffset",
+            "renderCount": 5,
+            "playgroundId": "#3DBA8X#1"
+        },
+        {
+            "title": "cube with holes using stencil buffer",
+            "playgroundId": "#CW5PRI#0"
+        },
+        {
+            "title": "water material",
+            "playgroundId": "#EUH2VL#0"
+        },
+        {
+            "title": "show bounding box",
+            "renderCount": 5,
+            "playgroundId": "#0LN1JD#0"
+        },
+        {
+            "title": "cube reflection with probe and mirrors",
+            "renderCount": 20,
+            "playgroundId": "#X3V1NN#0"
+        },
+        {
+            "title": "sphere with custom shader to display wireframe using glow layer",
+            "playgroundId": "#Y05E2C#0"
+        },
+        {
+            "title": "blur cube with the effect renderer",
+            "renderCount": 20,
+            "playgroundId": "#4C900K#2"
+        },
+        {
+            "title": "simple render target with blue spheres",
+            "playgroundId": "#NRR7F4#0"
+        },
+        {
+            "title": "neon pipe with glow layer",
+            "renderCount": 5,
+            "playgroundId": "#X229PI#0"
+        },
+        {
+            "title": "pillars sphere and torus with PCSS shadows",
+            "playgroundId": "#WL4Q8J#0"
+        },
+        {
+            "title": "soft transparent shadows",
+            "playgroundId": "#G3DJGA#0"
+        },
+        {
+            "title": "default render pipeline",
+            "playgroundId": "#GAFR36#0"
+        },
+        {
+            "title": "torus knot mirror",
+            "playgroundId": "#M5GFLR#0"
+        },
+        {
+            "title": "simple sphere in 4 mirrors",
+            "playgroundId": "#58CFTW#0"
+        },
+        {
+            "title": "procedural texture with node material",
+            "renderCount": 10,
+            "playgroundId": "#IA4X0H#0"
+        },
+        {
+            "title": "apply all post processes",
+            "renderCount": 10,
+            "playgroundId": "#MJ59Y8#2"
+        },
+        {
+            "title": "simple custom shader",
+            "renderCount": 5,
+            "playgroundId": "#6GFJNR#1"
+        },
+        {
+            "title": "show multiple guis",
+            "renderCount": 5,
+            "playgroundId": "#6X9UMD#11"
+        },
+        {
+            "title": "skybox with boombox",
+            "renderCount": 20,
+            "playgroundId": "#I2TR8G#0"
+        },
+        {
+            "title": "show all procedural textures",
+            "renderCount": 5,
+            "playgroundId": "#4N0QRP#0"
+        }
+    ]
+}