diff options
Diffstat (limited to 'dom/canvas/test/webgl-conf/checkout/conformance2/extensions')
5 files changed, 980 insertions, 0 deletions
diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/extensions/00_test_list.txt b/dom/canvas/test/webgl-conf/checkout/conformance2/extensions/00_test_list.txt new file mode 100644 index 000000000..7ce7c8b57 --- /dev/null +++ b/dom/canvas/test/webgl-conf/checkout/conformance2/extensions/00_test_list.txt @@ -0,0 +1,4 @@ +ext-color-buffer-float.html +ext-disjoint-timer-query-webgl2.html +promoted-extensions.html +promoted-extensions-in-shaders.html diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/extensions/ext-color-buffer-float.html b/dom/canvas/test/webgl-conf/checkout/conformance2/extensions/ext-color-buffer-float.html new file mode 100644 index 000000000..58cb9becd --- /dev/null +++ b/dom/canvas/test/webgl-conf/checkout/conformance2/extensions/ext-color-buffer-float.html @@ -0,0 +1,419 @@ +<!-- + +/* +** Copyright (c) 2015 The Khronos Group Inc. +** +** Permission is hereby granted, free of charge, to any person obtaining a +** copy of this software and/or associated documentation files (the +** "Materials"), to deal in the Materials without restriction, including +** without limitation the rights to use, copy, modify, merge, publish, +** distribute, sublicense, and/or sell copies of the Materials, and to +** permit persons to whom the Materials are furnished to do so, subject to +** the following conditions: +** +** The above copyright notice and this permission notice shall be included +** in all copies or substantial portions of the Materials. +** +** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. +*/ + +--> + +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>WebGL EXT_color_buffer_float Conformance Tests</title> +<link rel="stylesheet" href="../../resources/js-test-style.css"/> +<script src="../../js/js-test-pre.js"></script> +<script src="../../js/webgl-test-utils.js"></script> +</head> +<body> +<div id="description"></div> +<canvas id="canvas" style="width: 50px; height: 50px;"> </canvas> +<div id="console"></div> +<!-- Shaders for testing floating-point textures --> +<script id="testFragmentShader" type="x-shader/x-fragment"> +precision mediump float; +uniform sampler2D tex; +uniform vec4 subtractor; +varying vec2 texCoord; +void main() +{ + vec4 color = texture2D(tex, texCoord); + if (abs(color.r - subtractor.r) + + abs(color.g - subtractor.g) + + abs(color.b - subtractor.b) + + abs(color.a - subtractor.a) < 16.0) { + gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0); + } else { + gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); + } +} +</script> +<!-- Shaders for testing floating-point render targets --> +<script id="floatingPointFragmentShader" type="x-shader/x-fragment"> +void main() +{ + gl_FragColor = vec4(1000.0, 1000.0, 1000.0, 1000.0); +} +</script> +<script> +"use strict"; + +function allocateTexture() +{ + var texture = gl.createTexture(); + gl.bindTexture(gl.TEXTURE_2D, texture); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); + wtu.glErrorShouldBe(gl, gl.NO_ERROR, "texture parameter setup should succeed"); + return texture; +} + +function checkRenderingResults() +{ + wtu.checkCanvas(gl, [0, 255, 0, 255], "should be green"); +} + +function arrayToString(arr, size) { + var mySize; + if (!size) + mySize = arr.length; + else + mySize = size; + var out = "["; + for (var ii = 0; ii < mySize; ++ii) { + if (ii > 0) { + out += ", "; + } + out += arr[ii]; + } + return out + "]"; +} + +function runReadbackTest(testProgram, subtractor) +{ + // Verify floating point readback + debug("Checking readback of floating-point values"); + var buf = new Float32Array(4); + gl.readPixels(0, 0, 1, 1, gl.RGBA, gl.FLOAT , buf); + wtu.glErrorShouldBe(gl, gl.NO_ERROR, "readPixels from floating-point framebuffer should succeed"); + var ok = true; + var tolerance = 8.0; // TODO: factor this out from both this test and the subtractor shader above. + for (var ii = 0; ii < buf.length; ++ii) { + if (Math.abs(buf[ii] - subtractor[ii]) > tolerance) { + ok = false; + break; + } + } + if (ok) { + testPassed("readPixels of float-type data from floating-point framebuffer succeeded"); + } else { + testFailed("readPixels of float-type data from floating-point framebuffer failed: expected " + + arrayToString(subtractor, 4) + ", got " + arrayToString(buf)); + } +} + +function runFloatTextureRenderTargetTest(enabled, internalFormat, format, testProgram, numberOfChannels, subtractor, texSubImageCover) +{ + var formatString = wtu.glEnumToString(gl, internalFormat); + debug(""); + debug("testing floating-point " + formatString + " texture render target" + (texSubImageCover > 0 ? " after calling texSubImage" : "")); + + var texture = allocateTexture(); + var width = 2; + var height = 2; + gl.texImage2D(gl.TEXTURE_2D, 0, internalFormat, width, height, 0, format, gl.FLOAT, null); + wtu.glErrorShouldBe(gl, gl.NO_ERROR, "floating-point texture allocation should succeed"); + + // Try to use this texture as a render target. + var fbo = gl.createFramebuffer(); + gl.bindFramebuffer(gl.FRAMEBUFFER, fbo); + gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0); + gl.bindTexture(gl.TEXTURE_2D, null); + + var completeStatus = gl.checkFramebufferStatus(gl.FRAMEBUFFER); + if (!enabled) { + if (completeStatus == gl.FRAMEBUFFER_COMPLETE && !enabled) + testFailed("floating-point " + formatString + " render target should not be supported without enabling EXT_color_buffer_float"); + else + testPassed("floating-point " + formatString + " render target should not be supported without enabling EXT_color_buffer_float"); + return; + } + + if (completeStatus != gl.FRAMEBUFFER_COMPLETE) { + testFailed("floating-point " + formatString + " render target not supported"); + return; + } + + if (texSubImageCover > 0) { + // Ensure that replacing the whole texture or a part of it with texSubImage2D doesn't affect renderability + gl.bindTexture(gl.TEXTURE_2D, texture); + var data = new Float32Array(width * height * numberOfChannels * texSubImageCover); + gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, width, height * texSubImageCover, format, gl.FLOAT, data); + wtu.glErrorShouldBe(gl, gl.NO_ERROR, "texSubImage2D should succeed if EXT_color_buffer_float is enabled"); + gl.bindTexture(gl.TEXTURE_2D, null); + if (gl.checkFramebufferStatus(gl.FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE) { + testFailed("render target support changed after calling texSubImage2D"); + return; + } + } + + var renderProgram = + wtu.setupProgram(gl, + [wtu.simpleVertexShader, "floatingPointFragmentShader"], + ['vPosition'], + [0]); + wtu.clearAndDrawUnitQuad(gl); + wtu.glErrorShouldBe(gl, gl.NO_ERROR, "rendering to floating-point texture should succeed"); + + // Now sample from the floating-point texture and verify we got the correct values. + gl.bindFramebuffer(gl.FRAMEBUFFER, null); + gl.bindTexture(gl.TEXTURE_2D, texture); + gl.useProgram(testProgram); + gl.uniform1i(gl.getUniformLocation(testProgram, "tex"), 0); + gl.uniform4fv(gl.getUniformLocation(testProgram, "subtractor"), subtractor); + wtu.clearAndDrawUnitQuad(gl); + wtu.glErrorShouldBe(gl, gl.NO_ERROR, "rendering from floating-point texture should succeed"); + checkRenderingResults(); + + gl.bindFramebuffer(gl.FRAMEBUFFER, fbo); + runReadbackTest(testProgram, subtractor); +} + +function runFloatRenderbufferRenderTargetTest(enabled, internalFormat, testProgram, numberOfChannels, subtractor) +{ + var formatString = wtu.glEnumToString(gl, internalFormat); + var samples = [0]; + if (enabled) { + samples = Array.prototype.slice.call(gl.getInternalformatParameter(gl.RENDERBUFFER, internalFormat, gl.SAMPLES)); + samples.push(0); + } + for (var ndx = 0; ndx < samples.length; ++ndx) { + debug(""); + debug("testing floating-point " + formatString + " renderbuffer render target with number of samples " + samples[ndx]); + + var colorbuffer = gl.createRenderbuffer(); + var width = 2; + var height = 2; + gl.bindRenderbuffer(gl.RENDERBUFFER, colorbuffer); + if (samples[ndx] == 0) + gl.renderbufferStorage(gl.RENDERBUFFER, internalFormat, width, height); + else + gl.renderbufferStorageMultisample(gl.RENDERBUFFER, samples[ndx], internalFormat, width, height); + if (!enabled) { + wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, "floating-point renderbuffer allocation should fail if EXT_color_buffer_float is not enabled"); + return; + } else { + wtu.glErrorShouldBe(gl, gl.NO_ERROR, "floating-point renderbuffer allocation should succeed if EXT_color_buffer_float is enabled"); + } + + // Try to use this renderbuffer as a render target. + var fbo = gl.createFramebuffer(); + gl.bindFramebuffer(gl.FRAMEBUFFER, fbo); + gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, colorbuffer); + + var completeStatus = gl.checkFramebufferStatus(gl.FRAMEBUFFER); + if (completeStatus != gl.FRAMEBUFFER_COMPLETE) { + testFailed("floating-point " + formatString + " render target not supported"); + return; + } + var resolveColorRbo = null; + var resolveFbo = null; + if (samples[ndx] > 0) { + resolveColorRbo = gl.createRenderbuffer(); + gl.bindRenderbuffer(gl.RENDERBUFFER, resolveColorRbo); + gl.renderbufferStorage(gl.RENDERBUFFER, internalFormat, width, height); + resolveFbo = gl.createFramebuffer(); + gl.bindFramebuffer(gl.FRAMEBUFFER, resolveFbo); + gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, resolveColorRbo); + completeStatus = gl.checkFramebufferStatus(gl.FRAMEBUFFER); + if (completeStatus != gl.FRAMEBUFFER_COMPLETE) { + testFailed("Failed to create resolve framebuffer"); + return; + } + } + gl.bindFramebuffer(gl.FRAMEBUFFER, fbo); + gl.clearColor(1000.0, 1000.0, 1000.0, 1000.0); + gl.clear(gl.COLOR_BUFFER_BIT); + + if (samples[ndx] > 0) { + gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, resolveFbo); + gl.blitFramebuffer(0, 0, width, height, 0, 0, width, height, gl.COLOR_BUFFER_BIT, gl.NEAREST); + gl.bindFramebuffer(gl.READ_FRAMEBUFFER, resolveFbo); + } + runReadbackTest(testProgram, subtractor); + } +} + +function runRGB16FNegativeTest() +{ + debug(""); + debug("testing RGB16F isn't color renderable"); + + var texture = allocateTexture(); + var width = 2; + var height = 2; + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB16F, width, height, 0, gl.RGB, gl.FLOAT, null); + wtu.glErrorShouldBe(gl, gl.NO_ERROR, "RGB16F texture allocation should succeed"); + + // Try to use this texture as a render target. + var fbo = gl.createFramebuffer(); + gl.bindFramebuffer(gl.FRAMEBUFFER, fbo); + gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0); + gl.bindTexture(gl.TEXTURE_2D, null); + + var completeStatus = gl.checkFramebufferStatus(gl.FRAMEBUFFER); + if (completeStatus == gl.FRAMEBUFFER_COMPLETE) + testFailed("RGB16F render target should not be supported with or without enabling EXT_color_buffer_float"); + else + testPassed("RGB16F render target should not be supported with or without enabling EXT_color_buffer_float"); + gl.deleteTexture(texture); + + var colorbuffer = gl.createRenderbuffer(); + gl.bindRenderbuffer(gl.RENDERBUFFER, colorbuffer); + gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGB16F, width, height); + wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, "RGB16F renderbuffer allocation should fail with or without enabling EXT_color_buffer_float"); + gl.bindRenderbuffer(gl.RENDERBUFFER, null); + gl.deleteRenderbuffer(colorbuffer); + + gl.bindFramebuffer(gl.FRAMEBUFFER, null); + gl.deleteFramebuffer(fbo); +} + +function runUniqueObjectTest() +{ + debug(""); + debug("Testing that getExtension() returns the same object each time"); + gl.getExtension("EXT_color_buffer_float").myProperty = 2; + webglHarnessCollectGarbage(); + shouldBe('gl.getExtension("EXT_color_buffer_float").myProperty', '2'); +} + +function runInternalFormatQueryTest() +{ + debug(""); + debug("testing the internal format query"); + + var maxSamples = gl.getParameter(gl.MAX_SAMPLES); + var formats = new Array(gl.RGBA16F, gl.R32F, gl.RG32F, gl.RGBA32F, gl.R16F, gl.RG16F, gl.R11F_G11F_B10F); + var firstMultiOnlyFormat = 4; + for (var fmt = 0; fmt < formats.length; ++fmt) { + var samples = gl.getInternalformatParameter(gl.RENDERBUFFER, formats[fmt], gl.SAMPLES); + if (fmt >= firstMultiOnlyFormat && (samples.length == 0 || samples[0] < maxSamples)) { + testFailed("the maximum value in SAMPLES should be at least " + maxSamples); + return; + } + + var prevSampleCount = 0; + var sampleCount; + for (var ndx = 0; ndx < samples.length; ++ndx, prevSampleCount = sampleCount) { + sampleCount = samples[ndx]; + // sample count must be > 0 + if (sampleCount <= 0) { + testFailed("Expected sample count to be at least one; got " + sampleCount); + return; + } + + // samples must be ordered descending + if (ndx > 0 && sampleCount >= prevSampleCount) { + testFailed("Expected sample count to be ordered in descending order; got " + prevSampleCount + " at index " + (ndx - 1) + ", and " + sampleCount + " at index " + ndx); + return; + } + } + } + testPassed("Internal format query succeeded"); +} + +description("This test verifies the functionality of the EXT_color_buffer_float extension, if it is available."); + +debug(""); + +var wtu = WebGLTestUtils; +var canvas = document.getElementById("canvas"); +var gl = wtu.create3DContext(canvas, null, 2); + +if (!gl) { + testFailed("WebGL context does not exist"); +} else { + testPassed("WebGL context exists"); + + var texturedShaders = [ + wtu.simpleTextureVertexShader, + "testFragmentShader" + ]; + var testProgram = + wtu.setupProgram(gl, + texturedShaders, + ['vPosition', 'texCoord0'], + [0, 1]); + var quadParameters = wtu.setupUnitQuad(gl, 0, 1); + + // Ensure these formats can't be used for rendering if the extension is disabled + runFloatTextureRenderTargetTest(false, gl.R16F, gl.RED); + runFloatTextureRenderTargetTest(false, gl.RG16F, gl.RG); + runFloatTextureRenderTargetTest(false, gl.RGBA16F, gl.RGBA); + runFloatTextureRenderTargetTest(false, gl.R32F, gl.RED); + runFloatTextureRenderTargetTest(false, gl.RG32F, gl.RG); + runFloatTextureRenderTargetTest(false, gl.RGBA32F, gl.RGBA); + runFloatTextureRenderTargetTest(false, gl.R11F_G11F_B10F, gl.RGB); + + runFloatRenderbufferRenderTargetTest(false, gl.R16F); + runFloatRenderbufferRenderTargetTest(false, gl.RG16F); + runFloatRenderbufferRenderTargetTest(false, gl.RGBA16F); + runFloatRenderbufferRenderTargetTest(false, gl.R32F); + runFloatRenderbufferRenderTargetTest(false, gl.RG32F); + runFloatRenderbufferRenderTargetTest(false, gl.RGBA32F); + runFloatRenderbufferRenderTargetTest(false, gl.R11F_G11F_B10F); + + // Ensure RGB16F can't be used for rendering. + runRGB16FNegativeTest(); + + if (!gl.getExtension("EXT_color_buffer_float")) { + testPassed("No EXT_color_buffer_float support -- this is legal"); + } else { + testPassed("Successfully enabled EXT_color_buffer_float extension"); + + runInternalFormatQueryTest(); + + runFloatTextureRenderTargetTest(true, gl.R16F, gl.RED, testProgram, 1, [1000, 1, 1, 1], 0); + runFloatTextureRenderTargetTest(true, gl.RG16F, gl.RG, testProgram, 2, [1000, 1000, 1, 1], 0); + runFloatTextureRenderTargetTest(true, gl.RGBA16F, gl.RGBA, testProgram, 4, [1000, 1000, 1000, 1000], 0); + runFloatTextureRenderTargetTest(true, gl.R32F, gl.RED, testProgram, 1, [1000, 1, 1, 1], 0); + runFloatTextureRenderTargetTest(true, gl.RG32F, gl.RG, testProgram, 2, [1000, 1000, 1, 1], 0); + runFloatTextureRenderTargetTest(true, gl.RGBA32F, gl.RGBA, testProgram, 4, [1000, 1000, 1000, 1000], 0); + runFloatTextureRenderTargetTest(true, gl.R11F_G11F_B10F, gl.RGB, testProgram, 3, [1000, 1000, 1000, 1], 0); + runFloatTextureRenderTargetTest(true, gl.RGBA32F, gl.RGBA, testProgram, 4, [1000, 1000, 1000, 1000], 1); + runFloatTextureRenderTargetTest(true, gl.RGBA32F, gl.RGBA, testProgram, 4, [1000, 1000, 1000, 1000], 0.5); + + runFloatRenderbufferRenderTargetTest(true, gl.R16F, testProgram, 1, [1000, 1, 1, 1]); + runFloatRenderbufferRenderTargetTest(true, gl.RG16F, testProgram, 2, [1000, 1000, 1, 1]); + runFloatRenderbufferRenderTargetTest(true, gl.RGBA16F, testProgram, 4, [1000, 1000, 1000, 1000]); + runFloatRenderbufferRenderTargetTest(true, gl.R32F, testProgram, 1, [1000, 1, 1, 1]); + runFloatRenderbufferRenderTargetTest(true, gl.RG32F, testProgram, 2, [1000, 1000, 1, 1]); + runFloatRenderbufferRenderTargetTest(true, gl.RGBA32F, testProgram, 4, [1000, 1000, 1000, 1000]); + runFloatRenderbufferRenderTargetTest(true, gl.R11F_G11F_B10F, testProgram, 3, [1000, 1000, 1000, 1]); + + // Ensure EXT_color_buffer_float does not enable RGB16F as color renderable. + runRGB16FNegativeTest(); + + runUniqueObjectTest(); + } +} + +debug(""); +var successfullyParsed = true; +</script> +<script src="../../js/js-test-post.js"></script> + +</body> +</html> diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/extensions/ext-disjoint-timer-query-webgl2.html b/dom/canvas/test/webgl-conf/checkout/conformance2/extensions/ext-disjoint-timer-query-webgl2.html new file mode 100644 index 000000000..8969c108a --- /dev/null +++ b/dom/canvas/test/webgl-conf/checkout/conformance2/extensions/ext-disjoint-timer-query-webgl2.html @@ -0,0 +1,335 @@ +<!-- +/* +** Copyright (c) 2015-2016 The Khronos Group Inc. +** +** Permission is hereby granted, free of charge, to any person obtaining a +** copy of this software and/or associated documentation files (the +** "Materials"), to deal in the Materials without restriction, including +** without limitation the rights to use, copy, modify, merge, publish, +** distribute, sublicense, and/or sell copies of the Materials, and to +** permit persons to whom the Materials are furnished to do so, subject to +** the following conditions: +** +** The above copyright notice and this permission notice shall be included +** in all copies or substantial portions of the Materials. +** +** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. +*/ +--> + +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>WebGL 2 EXT_disjoint_timer_query_webgl2 Conformance Tests</title> +<link rel="stylesheet" href="../../resources/js-test-style.css"/> +<script src="../../js/js-test-pre.js"></script> +<script src="../../js/webgl-test-utils.js"></script> +</head> +<body> +<div id="description"></div> +<canvas id="canvas" style="width: 50px; height: 50px;"> </canvas> +<div id="console"></div> + +<script> +"use strict"; +description("This test verifies the functionality of the EXT_disjoint_timer_query_webgl2 extension, if it is available."); + +var wtu = WebGLTestUtils; +var canvas = document.getElementById("canvas"); +var gl = wtu.create3DContext(canvas, null, 2); +var ext = null; +var query = null; +var query2 = null; +var elapsed_query = null; +var timestamp_query1 = null; +var timestamp_query2 = null; +var availability_retry = 500; +var timestamp_counter_bits = 0; + +if (!gl) { + testFailed("WebGL context does not exist"); + finishTest(); +} else { + testPassed("WebGL context exists"); + + // Query the extension and store globally so shouldBe can access it + ext = wtu.getExtensionWithKnownPrefixes(gl, "EXT_disjoint_timer_query_webgl2"); + if (!ext) { + testPassed("No EXT_disjoint_timer_query_webgl2 support -- this is legal"); + finishTest(); + } else { + runSanityTests(); + wtu.glErrorShouldBe(gl, gl.NO_ERROR); + + // Clear disjoint value. + gl.getParameter(ext.GPU_DISJOINT_EXT); + wtu.glErrorShouldBe(gl, gl.NO_ERROR); + + runElapsedTimeTest(); + wtu.glErrorShouldBe(gl, gl.NO_ERROR); + + timestamp_counter_bits = gl.getQuery(ext.TIMESTAMP_EXT, ext.QUERY_COUNTER_BITS_EXT); + if (timestamp_counter_bits > 0) { + runTimeStampTest(); + wtu.glErrorShouldBe(gl, gl.NO_ERROR); + } + verifyQueryResultsNotAvailable(); + wtu.glErrorShouldBe(gl, gl.NO_ERROR); + + window.requestAnimationFrame(checkQueryResults); + } +} + +function runSanityTests() { + debug(""); + debug("Testing other query types"); + query = gl.createQuery(); + gl.beginQuery(gl.ANY_SAMPLES_PASSED, query); + shouldBeTrue("gl.getQuery(gl.ANY_SAMPLES_PASSED, gl.CURRENT_QUERY) !== null"); + gl.endQuery(gl.ANY_SAMPLES_PASSED); + wtu.glErrorShouldBe(gl, gl.NO_ERROR, "enabling EXT_disjoint_timer_query_webgl2 should not break other queries"); + + debug(""); + debug("Testing timer query expectations"); + + shouldBe("ext.QUERY_COUNTER_BITS_EXT", "0x8864"); + shouldBe("ext.TIME_ELAPSED_EXT", "0x88BF"); + shouldBe("ext.TIMESTAMP_EXT", "0x8E28"); + shouldBe("ext.GPU_DISJOINT_EXT", "0x8FBB"); + + shouldBe("gl.isQuery(null)", "false"); + + shouldBeTrue("gl.getQuery(ext.TIME_ELAPSED_EXT, gl.CURRENT_QUERY) === null"); + wtu.glErrorShouldBe(gl, gl.NO_ERROR); + shouldBeTrue("gl.getQuery(ext.TIME_ELAPSED_EXT, ext.QUERY_COUNTER_BITS_EXT) >= 30"); + wtu.glErrorShouldBe(gl, gl.NO_ERROR); + + shouldBeTrue("gl.getQuery(ext.TIMESTAMP_EXT, gl.CURRENT_QUERY) === null"); + wtu.glErrorShouldBe(gl, gl.NO_ERROR); + + // Certain drivers set timestamp counter bits to 0 as they don't support timestamps + shouldBeTrue("gl.getQuery(ext.TIMESTAMP_EXT, ext.QUERY_COUNTER_BITS_EXT) >= 30 || " + + "gl.getQuery(ext.TIMESTAMP_EXT, ext.QUERY_COUNTER_BITS_EXT) === 0"); + wtu.glErrorShouldBe(gl, gl.NO_ERROR); + + debug(""); + debug("Testing time elapsed query lifecycle"); + query = gl.createQuery(); + shouldBe("gl.isQuery(query)", "false"); + wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Query creation must succeed."); + gl.beginQuery(ext.TIMESTAMP_EXT, query); + wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, "Beginning a timestamp query should fail."); + gl.beginQuery(ext.TIME_ELAPSED_EXT, query); + shouldBe("gl.isQuery(query)", "true"); + wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Beginning an inactive time elapsed query should succeed."); + gl.beginQuery(ext.TIME_ELAPSED_EXT, query); + wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "Attempting to begin an active query should fail."); + gl.getQueryParameter(query, gl.QUERY_RESULT_AVAILABLE); + wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "Fetching query result availability of an active query should fail."); + gl.getQueryParameter(query, gl.QUERY_RESULT_EXT); + wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "Fetching query result of an active query should fail."); + shouldBe("gl.getQuery(ext.TIME_ELAPSED_EXT, gl.CURRENT_QUERY)", "query"); + gl.endQuery(ext.TIME_ELAPSED_EXT); + wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Ending an active time elapsed query should succeed."); + gl.getQueryParameter(query, gl.QUERY_RESULT_AVAILABLE); + wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Fetching query result availability after query end should succeed."); + gl.endQuery(ext.TIME_ELAPSED_EXT); + wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "Attempting to end an inactive query should fail."); + ext.queryCounterEXT(query, ext.TIMESTAMP_EXT); + wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "Should not be able to use time elapsed query to store a timestamp."); + gl.deleteQuery(query); + wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Query deletion must succeed."); + gl.beginQuery(ext.TIME_ELAPSED_EXT, query); + wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "Beginning a deleted query must fail."); + gl.getQueryParameter(query, gl.QUERY_RESULT_AVAILABLE); + wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "Fetching query result availability after query deletion should fail."); + shouldBe("gl.isQuery(query)", "false"); + + debug(""); + debug("Testing timestamp counter"); + query = gl.createQuery(); + shouldThrow("ext.queryCounterEXT(null, ext.TIMESTAMP_EXT)"); + ext.queryCounterEXT(query, ext.TIMESTAMP_EXT); + wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Timestamp counter queries should work."); + gl.deleteQuery(query); + wtu.glErrorShouldBe(gl, gl.NO_ERROR); + + debug(""); + debug("Performing parameter sanity checks"); + gl.getParameter(ext.TIMESTAMP_EXT); + wtu.glErrorShouldBe(gl, gl.NO_ERROR, "getParameter timestamp calls should work."); + gl.getParameter(ext.GPU_DISJOINT_EXT); + wtu.glErrorShouldBe(gl, gl.NO_ERROR, "getParameter disjoint calls should work."); + + debug(""); + debug("Testing current query conditions"); + query = gl.createQuery(); + query2 = gl.createQuery(); + shouldBe("gl.getQuery(ext.TIME_ELAPSED_EXT, gl.CURRENT_QUERY)", "null"); + gl.beginQuery(ext.TIME_ELAPSED_EXT, query); + shouldBe("gl.getQuery(ext.TIME_ELAPSED_EXT, gl.CURRENT_QUERY)", "query"); + wtu.glErrorShouldBe(gl, gl.NO_ERROR); + + debug(""); + debug("Testing failed begin query should not change the current query."); + gl.beginQuery(ext.TIME_ELAPSED_EXT, query2); + wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "Beginning an elapsed query without ending should fail."); + shouldBe("gl.getQuery(ext.TIME_ELAPSED_EXT, gl.CURRENT_QUERY)", "query"); + wtu.glErrorShouldBe(gl, gl.NO_ERROR); + + debug(""); + debug("Testing beginning a timestamp query is invalid and should not change the elapsed query."); + gl.beginQuery(ext.TIMESTAMP_EXT, query2) + wtu.glErrorShouldBe(gl, gl.INVALID_ENUM); + shouldBe("gl.getQuery(ext.TIME_ELAPSED_EXT, gl.CURRENT_QUERY)", "query"); + wtu.glErrorShouldBe(gl, gl.NO_ERROR); + + debug(""); + debug("Testing timestamp queries end immediately so are never current."); + ext.queryCounterEXT(query2, ext.TIMESTAMP_EXT); + shouldBe("gl.getQuery(ext.TIMESTAMP_EXT, gl.CURRENT_QUERY)", "null"); + wtu.glErrorShouldBe(gl, gl.NO_ERROR); + + debug(""); + debug("Testing ending the query should clear the current query."); + gl.endQuery(ext.TIME_ELAPSED_EXT); + shouldBe("gl.getQuery(ext.TIME_ELAPSED_EXT, gl.CURRENT_QUERY)", "null"); + wtu.glErrorShouldBe(gl, gl.NO_ERROR); + + debug(""); + debug("Testing beginning a elapsed query using a timestamp query should fail and not affect current query.") + gl.beginQuery(ext.TIME_ELAPSED_EXT, query2); + wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "Switching query targets should fail."); + shouldBe("gl.getQuery(ext.TIME_ELAPSED_EXT, gl.CURRENT_QUERY)", "null"); + wtu.glErrorShouldBe(gl, gl.NO_ERROR); + + gl.deleteQuery(query); + gl.deleteQuery(query2); + + wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors at end of sanity tests"); +} + +function runElapsedTimeTest() { + debug(""); + debug("Testing elapsed time query"); + + elapsed_query = gl.createQuery(); + gl.beginQuery(ext.TIME_ELAPSED_EXT, elapsed_query); + gl.clearColor(0, 0, 1, 1); + gl.clear(gl.COLOR_BUFFER_BIT); + gl.endQuery(ext.TIME_ELAPSED_EXT); + wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Time elapsed query should have no errors"); +} + +function runTimeStampTest() { + debug(""); + debug("Testing timestamp query"); + + timestamp_query1 = gl.createQuery(); + timestamp_query2 = gl.createQuery(); + ext.queryCounterEXT(timestamp_query1, ext.TIMESTAMP_EXT); + gl.clearColor(1, 0, 0, 1); + gl.clear(gl.COLOR_BUFFER_BIT); + ext.queryCounterEXT(timestamp_query2, ext.TIMESTAMP_EXT); + wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Timestamp queries should have no errors"); +} + +function verifyQueryResultsNotAvailable() { + debug(""); + debug("Verifying queries' results don't become available too early"); + + // Verify as best as possible that the implementation doesn't + // allow a query's result to become available the same frame, by + // spin-looping for some time and ensuring that none of the + // queries' results become available. + var startTime = Date.now(); + while (Date.now() - startTime < 2000) { + gl.finish(); + if (gl.getQueryParameter(elapsed_query, gl.QUERY_RESULT_AVAILABLE)) { + testFailed("One of the queries' results became available too early"); + return; + } + if (timestamp_counter_bits > 0) { + if (gl.getQueryParameter(timestamp_query1, gl.QUERY_RESULT_AVAILABLE) || + gl.getQueryParameter(timestamp_query2, gl.QUERY_RESULT_AVAILABLE)) { + testFailed("One of the queries' results became available too early"); + return; + } + } + } + + testPassed("Queries' results didn't become available in a spin loop"); +} + +function checkQueryResults() { + if (availability_retry > 0) { + // Make a reasonable attempt to wait for the queries' results to become available. + if (!gl.getQueryParameter(elapsed_query, gl.QUERY_RESULT_AVAILABLE) || + (timestamp_counter_bits > 0 && !gl.getQueryParameter(timestamp_query2, gl.QUERY_RESULT_AVAILABLE))) { + var error = gl.getError(); + if (error != gl.NO_ERROR) { + testFailed("getQueryParameter should have no errors: " + wtu.glEnumToString(gl, error)); + debug(""); + finishTest(); + return; + } + availability_retry--; + window.requestAnimationFrame(checkQueryResults); + return; + } + } + + debug(""); + debug("Testing query results"); + + // Make sure queries are available. + shouldBe("gl.getQueryParameter(elapsed_query, gl.QUERY_RESULT_AVAILABLE)", "true"); + if (timestamp_counter_bits > 0) { + shouldBe("gl.getQueryParameter(timestamp_query1, gl.QUERY_RESULT_AVAILABLE)", "true"); + shouldBe("gl.getQueryParameter(timestamp_query2, gl.QUERY_RESULT_AVAILABLE)", "true"); + } + + var disjoint_value = gl.getParameter(ext.GPU_DISJOINT_EXT); + if (disjoint_value) { + // Cannot validate results make sense, but this is okay. + testPassed("Disjoint triggered."); + } else { + var elapsed_result = gl.getQueryParameter(elapsed_query, gl.QUERY_RESULT_EXT); + if (timestamp_counter_bits > 0) { + var timestamp_result1 = gl.getQueryParameter(timestamp_query1, gl.QUERY_RESULT_EXT); + var timestamp_result2 = gl.getQueryParameter(timestamp_query2, gl.QUERY_RESULT_EXT); + } + // Do some basic validity checking of the elapsed time query. There's no way it should + // take more than about half a second for a no-op query. + var halfSecondInNanos = 0.5 * 1000 * 1000 * 1000; + if (elapsed_result < 0 || elapsed_result > halfSecondInNanos) { + testFailed("Time elapsed query returned invalid data: " + elapsed_result); + } else { + testPassed("Time elapsed query results were valid."); + } + + if (timestamp_counter_bits > 0) { + if (timestamp_result1 <= 0 || + timestamp_result2 <= 0 || + timestamp_result2 <= timestamp_result1) { + testFailed("Timestamp queries returned invalid data: timestamp_result1 = " + + timestamp_result1 + ", timestamp_result2 = " + timestamp_result2); + } else { + testPassed("Timestamp query results were valid."); + } + } + } + + debug(""); + finishTest(); +} +</script> +</body> +</html> diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/extensions/promoted-extensions-in-shaders.html b/dom/canvas/test/webgl-conf/checkout/conformance2/extensions/promoted-extensions-in-shaders.html new file mode 100644 index 000000000..8892adec5 --- /dev/null +++ b/dom/canvas/test/webgl-conf/checkout/conformance2/extensions/promoted-extensions-in-shaders.html @@ -0,0 +1,136 @@ +<!-- + +/* +** Copyright (c) 2015 The Khronos Group Inc. +** +** Permission is hereby granted, free of charge, to any person obtaining a +** copy of this software and/or associated documentation files (the +** "Materials"), to deal in the Materials without restriction, including +** without limitation the rights to use, copy, modify, merge, publish, +** distribute, sublicense, and/or sell copies of the Materials, and to +** permit persons to whom the Materials are furnished to do so, subject to +** the following conditions: +** +** The above copyright notice and this permission notice shall be included +** in all copies or substantial portions of the Materials. +** +** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. +*/ + +--> + +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>Extensions promoted to core should not be possible to use in shaders</title> +<link rel="stylesheet" href="../../resources/js-test-style.css"/> +<link rel="stylesheet" href="../../resources/glsl-feature-tests.css"/> +<script src="../../js/js-test-pre.js"></script> +<script src="../../js/webgl-test-utils.js"></script> +<script src="../../js/glsl-conformance-test.js"></script> +</head> +<body> +<div id="description"></div> +<div id="console"></div> +<script id="fragShaderRequire" type="x-shader/x-fragment"> +#extension $(ext) : require +precision mediump float; +void main() { + gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0); +} +</script> +<script id="fragShaderIfdef" type="x-shader/x-fragment"> +precision mediump float; +void main() { +#ifdef $(ext) + gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); +#else + gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0); +#endif +} +</script> +<script id="fragShader300Require" type="x-shader/x-fragment">#version 300 es +#extension $(ext) : require +precision mediump float; +out vec4 my_FragColor; +void main() { + my_FragColor = vec4(0.0, 1.0, 0.0, 1.0); +} +</script> +<script id="fragShader300Ifdef" type="x-shader/x-fragment">#version 300 es +precision mediump float; +out vec4 my_FragColor; +void main() { +#ifdef $(ext) + my_FragColor = vec4(1.0, 0.0, 0.0, 1.0); +#else + my_FragColor = vec4(0.0, 1.0, 0.0, 1.0); +#endif +} +</script> +<script type="application/javascript"> +"use strict"; +description(); + +var wtu = WebGLTestUtils; + +var shaderTemplateRequire = wtu.getScript('fragShaderRequire'); +var shaderTemplate300Require = wtu.getScript('fragShader300Require'); +var shaderTemplateIfdef = wtu.getScript('fragShaderIfdef'); +var shaderTemplate300Ifdef = wtu.getScript('fragShader300Ifdef'); + +var extensions = [ + 'GL_EXT_draw_buffers', + 'GL_EXT_frag_depth', + 'GL_EXT_shader_texture_lod', + 'GL_OES_standard_derivatives' +]; + +var tests = []; + +for (var i = 0; i < extensions.length; ++i) { + var shaderSrcRequire = wtu.replaceParams(shaderTemplateRequire, {'ext': extensions[i]}); + tests.push({ + fShaderSource: shaderSrcRequire, + fShaderSuccess: false, + linkSuccess: false, + passMsg: "ESSL 1.00 Fragment shader that requires " + extensions[i] + " should not compile." + }); + var shaderSrc300Require = wtu.replaceParams(shaderTemplate300Require, {'ext': extensions[i]}); + tests.push({ + fShaderSource: shaderSrc300Require, + fShaderSuccess: false, + linkSuccess: false, + passMsg: "ESSL 3.00 Fragment shader that requires " + extensions[i] + " should not compile." + }); + + var shaderSrcIfdef = wtu.replaceParams(shaderTemplateIfdef, {'ext': extensions[i]}); + tests.push({ + fShaderSource: shaderSrcIfdef, + fShaderSuccess: true, + linkSuccess: true, + render: true, + passMsg: extensions[i] + " should not be defined in ESSL 1.00 fragment shader." + }); + var shaderSrc300Ifdef = wtu.replaceParams(shaderTemplate300Ifdef, {'ext': extensions[i]}); + tests.push({ + fShaderSource: shaderSrc300Ifdef, + fShaderSuccess: true, + linkSuccess: true, + render: true, + passMsg: extensions[i] + " should not be defined in ESSL 3.00 fragment shader." + }); +} + +GLSLConformanceTester.runTests(tests, 2); +var successfullyParsed = true; +</script> +</body> +</html> diff --git a/dom/canvas/test/webgl-conf/checkout/conformance2/extensions/promoted-extensions.html b/dom/canvas/test/webgl-conf/checkout/conformance2/extensions/promoted-extensions.html new file mode 100644 index 000000000..fe93eeec7 --- /dev/null +++ b/dom/canvas/test/webgl-conf/checkout/conformance2/extensions/promoted-extensions.html @@ -0,0 +1,86 @@ +<!-- + +/* +** Copyright (c) 2016 The Khronos Group Inc. +** +** Permission is hereby granted, free of charge, to any person obtaining a +** copy of this software and/or associated documentation files (the +** "Materials"), to deal in the Materials without restriction, including +** without limitation the rights to use, copy, modify, merge, publish, +** distribute, sublicense, and/or sell copies of the Materials, and to +** permit persons to whom the Materials are furnished to do so, subject to +** the following conditions: +** +** The above copyright notice and this permission notice shall be included +** in all copies or substantial portions of the Materials. +** +** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. +*/ + +--> + +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<link rel="stylesheet" href="../../resources/js-test-style.css"/> +<script src="../../js/js-test-pre.js"></script> +<script src="../../js/webgl-test-utils.js"></script> +</head> +<body> +<div id="description"></div> +<div id="console"></div> + +<script> +"use strict"; +var wtu = WebGLTestUtils; +var gl; + +function checkExtensionNotAvailable(extension, extensions) { + if (extensions.indexOf(extension) >= 0) { + testFailed(extension + " was exposed in the WebGL 2.0 context but should not have been"); + } else { + testPassed(extension + " was not exposed in the WebGL 2.0 context"); + } +} + +description("Promoted extensions from WebGL 1.0 should not be exposed in WebGL 2.0"); + +shouldBeNonNull("gl = wtu.create3DContext(undefined, undefined, 2)"); + +var exts = gl.getSupportedExtensions(); + +var promotedExtensions = [ + "ANGLE_instanced_arrays", + "EXT_blend_minmax", + "EXT_color_buffer_half_float", + "EXT_frag_depth", + "EXT_shader_texture_lod", + "EXT_sRGB", + "OES_element_index_uint", + "OES_standard_derivatives", + "OES_texture_float", + "OES_texture_half_float", + "OES_texture_half_float_linear", + "OES_vertex_array_object", + "WEBGL_depth_texture", + "WEBGL_draw_buffers", +] + +for (var i = 0; i < promotedExtensions.length; ++i) { + checkExtensionNotAvailable(promotedExtensions[i], exts); +} + +debug("") +var successfullyParsed = true; +</script> + +<script src="../../js/js-test-post.js"></script> +</body> +</html> |