Bug 1534937 - Update webgl-conf checkout to tip. r=lsalzman

Differential Revision: https://phabricator.services.mozilla.com/D28592

--HG--
rename : dom/canvas/test/webgl-conf/checkout/conformance/rendering/out-of-bounds-index-buffers.html => dom/canvas/test/webgl-conf/checkout/conformance/rendering/out-of-bounds-array-buffers.html
rename : dom/canvas/test/webgl-conf/checkout/conformance/attribs/gl-bindAttribLocation-aliasing.html => dom/canvas/test/webgl-conf/checkout/conformance2/extensions/ext-float-blend.html
rename : dom/canvas/test/webgl-conf/checkout/conformance2/extensions/webgl_multiview.html => dom/canvas/test/webgl-conf/checkout/conformance2/extensions/ovr_multiview2.html
rename : dom/canvas/test/webgl-conf/checkout/conformance2/extensions/webgl_multiview_depth.html => dom/canvas/test/webgl-conf/checkout/conformance2/extensions/ovr_multiview2_depth.html
rename : dom/canvas/test/webgl-conf/checkout/conformance2/extensions/webgl_multiview_draw_buffers.html => dom/canvas/test/webgl-conf/checkout/conformance2/extensions/ovr_multiview2_draw_buffers.html
rename : dom/canvas/test/webgl-conf/checkout/conformance2/extensions/webgl_multiview_flat_varying.html => dom/canvas/test/webgl-conf/checkout/conformance2/extensions/ovr_multiview2_flat_varying.html
rename : dom/canvas/test/webgl-conf/checkout/conformance2/extensions/webgl_multiview_instanced_draw.html => dom/canvas/test/webgl-conf/checkout/conformance2/extensions/ovr_multiview2_instanced_draw.html
rename : dom/canvas/test/webgl-conf/checkout/conformance2/extensions/webgl_multiview_non_multiview_shaders.html => dom/canvas/test/webgl-conf/checkout/conformance2/extensions/ovr_multiview2_non_multiview_shaders.html
rename : dom/canvas/test/webgl-conf/checkout/conformance2/extensions/webgl_multiview_single_view_operations.html => dom/canvas/test/webgl-conf/checkout/conformance2/extensions/ovr_multiview2_single_view_operations.html
rename : dom/canvas/test/webgl-conf/checkout/conformance2/extensions/webgl_multiview_timer_query.html => dom/canvas/test/webgl-conf/checkout/conformance2/extensions/ovr_multiview2_timer_query.html
rename : dom/canvas/test/webgl-conf/checkout/conformance2/extensions/webgl_multiview_transform_feedback.html => dom/canvas/test/webgl-conf/checkout/conformance2/extensions/ovr_multiview2_transform_feedback.html
rename : dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/tex-unpack-params-imagedata.html => dom/canvas/test/webgl-conf/checkout/conformance2/textures/misc/generate-mipmap-with-large-base-level.html
rename : dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/common_functions.html => dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/common_functions_00.html
rename : dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/geometric.html => dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/common_functions_01.html
rename : dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/float_compare.html => dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/common_functions_02.html
rename : dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/int_compare.html => dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/common_functions_03.html
rename : dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/bool_compare.html => dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/common_functions_04.html
rename : dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/selection.html => dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/common_functions_05.html
rename : dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/sequence.html => dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/common_functions_06.html
rename : dom/canvas/test/webgl-conf/checkout/js/tests/webgl_multiview_util.js => dom/canvas/test/webgl-conf/checkout/js/tests/ovr_multiview2_util.js
extra : moz-landing-system : lando
This commit is contained in:
Jeff Gilbert 2019-04-24 03:34:48 +00:00
Родитель 3415e4de5f
Коммит 88d6589226
189 изменённых файлов: 12850 добавлений и 4208 удалений

Просмотреть файл

@ -23,8 +23,7 @@ a formal conformance submission.
4. Verify that the User Agent and WebGL renderer strings identify your browser and target correctly.
5. Copy the contents of the text summary (starting with "WebGL Conformance Test Results") and send via email to
webgl_conformance_submissions@khronos.org
5. Submit a PR with the results to [https://github.com/KhronosGroup/WebGLConformanceSubmissions].
Please see CONFORMANCE_RULES.txt in this directory for guidelines
about what constitutes a conformant WebGL implementation.
@ -77,4 +76,4 @@ The dates below are when work on the conformance suite version was started.
- 2013/02/14: Version 1.0.3
- 2013/10/11: Version 2.0.0
- 2014/11/14: Version 1.0.4
- 2016/11/21: Version 2.0.1
- 2016/11/21: Version 2.0.1

Просмотреть файл

@ -3,6 +3,7 @@
--min-version 1.0.4 gl-bindAttribLocation-nonexistent-attribute.html
--min-version 1.0.4 gl-bindAttribLocation-repeated.html
--min-version 1.0.2 gl-disabled-vertex-attrib.html
--min-version 1.0.4 gl-disabled-vertex-attrib-update.html
gl-enable-vertex-attrib.html
--min-version 1.0.3 gl-matrix-attributes.html
--max-version 1.9.9 gl-vertex-attrib.html
@ -11,3 +12,4 @@ gl-vertexattribpointer-offsets.html
--min-version 1.0.2 gl-vertex-attrib-render.html
gl-vertex-attrib-zero-issues.html
--min-version 1.0.4 gl-vertex-attrib-unconsumed-out-of-bounds.html
--min-version 1.0.4 gl-vertex-attrib-context-switch.html

Просмотреть файл

@ -1,26 +1,7 @@
<!--
/*
** Copyright (c) 2014 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.
*/
Copyright (c) 2019 The Khronos Group Inc.
Use of this source code is governed by an MIT-style license that can be
found in the LICENSE.txt file.
-->
<!DOCTYPE html>
<html>

Просмотреть файл

@ -0,0 +1,100 @@
<!--
/*
** Copyright (c) 2018 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 Disabled Vertex Attrib Update Test</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>
<canvas id="example" width="50" height="50">
</canvas>
<div id="description"></div>
<div id="console"></div>
<script id="vshader" type="x-shader/x-vertex">
attribute vec4 a_position;
attribute float a_actualValue;
uniform float u_expectedValue;
varying float v_result;
void main() {
gl_Position = a_position;
v_result = a_actualValue == u_expectedValue ? 1.0 : 0.0;
}
</script>
<script id="fshader" type="x-shader/x-fragment">
precision mediump float;
varying float v_result;
void main() {
gl_FragColor = v_result > 0.0 ? vec4(0.0, 1.0, 0.0, 1.0) : vec4(1.0, 0.0, 0.0, 1.0);
}
</script>
<script>
// Tests that repeatedly updating a disabled vertex attribute works as expected.
// This covers an ANGLE bug where dirty bits for current values were ignoring repeated updates.
// Based on ANGLE test (VertexAttributeTest, DisabledAttribUpdates) from https://github.com/google/angle/blob/f7f0b8c3ab21c52cc2915048959361cf628d95f0/src/tests/gl_tests/VertexAttributeTest.cpp
"use strict";
var wtu = WebGLTestUtils;
description();
var gl = wtu.create3DContext("example");
var program = wtu.setupProgram(gl, ['vshader', 'fshader']);
gl.useProgram(program);
var positionLocation = gl.getAttribLocation(program, "a_position");
var attribLoc = gl.getAttribLocation(program, "a_actualValue");
gl.vertexAttribPointer(attribLoc, 1, gl.FLOAT, gl.FALSE, 0, 0);
var uniLoc = gl.getUniformLocation(program, "u_expectedValue");
var gridRes = 1;
wtu.setupIndexedQuad(gl, gridRes, positionLocation);
var testValues = [1, 2, 3, 4];
for (var i = 0; i < testValues.length; ++i) {
var testValue = testValues[i];
gl.uniform1f(uniLoc, testValue);
gl.vertexAttrib1f(attribLoc, testValue);
wtu.clearAndDrawIndexedQuad(gl, gridRes);
wtu.checkCanvas(gl, [0, 255, 0, 255], "should be green");
}
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no errors");
var successfullyParsed = true;
</script>
<script src="../../js/js-test-post.js"></script>
</body>
</html>

Просмотреть файл

@ -0,0 +1,79 @@
<!--
/*
** Copyright (c) 2019 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 Vertex Attrib Context Switch Test</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>
<canvas id="one" width="50" height="50">
</canvas>
<canvas id="two" width="50" height="50">
</canvas>
<div id="description"></div>
<div id="console"></div>
<script>
"use strict";
description("tests that vertex attrib value is preserved across context switches");
var wtu = WebGLTestUtils;
var positionLocation = 0;
var colorLocation = 1;
var gridRes = 1;
var canvas1 = document.getElementById("one");
var gl1 = wtu.create3DContext(canvas1);
var program1 = wtu.setupSimpleVertexColorProgram(gl1, positionLocation, colorLocation);
gl1.vertexAttrib4f(colorLocation, 0.0, 1.0, 0.0, 1.0);
wtu.setupIndexedQuad(gl1, gridRes, positionLocation);
wtu.clearAndDrawIndexedQuad(gl1, gridRes);
wtu.checkCanvas(gl1, [0, 255, 0, 255], "should be green 1");
var canvas2 = document.getElementById("two");
var gl2 = wtu.create3DContext(canvas2);
var program2 = wtu.setupSimpleVertexColorProgram(gl2, positionLocation, colorLocation);
wtu.setupIndexedQuad(gl2, gridRes, positionLocation);
wtu.clearAndDrawIndexedQuad(gl2, gridRes);
wtu.checkCanvas(gl2, [0, 0, 0, 255], "should be black 1");
wtu.checkCanvas(gl1, [0, 255, 0, 255], "should be green 2");
wtu.clearAndDrawIndexedQuad(gl2, gridRes);
wtu.checkCanvas(gl2, [0, 0, 0, 255], "should be black 2");
wtu.clearAndDrawIndexedQuad(gl1, gridRes);
wtu.checkCanvas(gl1, [0, 255, 0, 255], "should be green 3");
var successfullyParsed = true;
</script>
<script src="../../js/js-test-post.js"></script>
</body>
</html>

Просмотреть файл

@ -51,7 +51,9 @@
</script>
<script id="fshader" type="x-shader/x-fragment">
void main() { }
void main() {
gl_FragColor = vec4(1);
}
</script>
<script>

Просмотреть файл

@ -10,4 +10,5 @@ index-validation-crash-with-buffer-sub-data.html
index-validation-verifies-too-many-indices.html
index-validation-with-resized-buffer.html
index-validation.html
--min-version 1.0.4 vertex-buffer-updated-after-draw.html

Просмотреть файл

@ -0,0 +1,115 @@
<!--
/*
** Copyright (c) 2018 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 Vertex Buffer Updated After Draw Test</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>
<canvas id="example" width="50" height="50">
</canvas>
<div id="description"></div>
<div id="console"></div>
<script id="vshader" type="x-shader/x-vertex">
attribute vec2 a_position;
attribute vec4 a_color;
varying vec4 v_outcolor;
void main() {
gl_Position = vec4(a_position, 0, 1);
v_outcolor = a_color;
}
</script>
<script id="fshader" type="x-shader/x-fragment">
varying mediump vec4 v_outcolor;
void main() {
gl_FragColor = v_outcolor;
}
</script>
<script>
// Tests that D3D11 dirty bit updates don't forget about BufferSubData attrib updates.
// Based on ANGLE test (StateChangeTest, VertexBufferUpdatedAfterDraw) from https://github.com/google/angle/blob/f7f0b8c3ab21c52cc2915048959361cf628d95f0/src/tests/gl_tests/StateChangeTest.cpp
"use strict";
var wtu = WebGLTestUtils;
description();
var gl = wtu.create3DContext("example");
var program = wtu.setupProgram(gl, ['vshader', 'fshader']);
var colorLoc = gl.getAttribLocation(program, "a_color");
var green = new Uint8Array(4 * 6);
var red = new Uint8Array(4 * 6);
for (var i = 0; i < 6; ++i) {
var ci = i * 4;
green[ci] = 0;
red[ci] = 255;
green[ci + 1] = 255;
red[ci + 1] = 0;
green[ci + 2] = red[ci + 2] = 0;
green[ci + 3] = red[ci + 3] = 255;
}
var positionLoc = gl.getAttribLocation(program, "a_position");
var gridRes = 1;
wtu.setupIndexedQuad(gl, gridRes, positionLoc);
var colorBuf = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, colorBuf);
gl.bufferData(gl.ARRAY_BUFFER, green, gl.STATIC_DRAW);
gl.vertexAttribPointer(colorLoc, 4, gl.UNSIGNED_BYTE, true, 0, 0);
gl.enableVertexAttribArray(colorLoc);
wtu.clearAndDrawIndexedQuad(gl, gridRes);
wtu.checkCanvas(gl, [0, 255, 0, 255], "should be green");
gl.bufferSubData(gl.ARRAY_BUFFER, 0, red);
wtu.clearAndDrawIndexedQuad(gl, gridRes);
wtu.checkCanvas(gl, [255, 0, 0, 255], "should be red");
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no errors");
var successfullyParsed = true;
</script>
<script src="../../js/js-test-post.js"></script>
</body>
</html>

Просмотреть файл

@ -0,0 +1,258 @@
<!--
/*
** Copyright (c) 2019 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>Deleted Object Behavior</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>
<div id="canvases">
<canvas id="canvas1">
</div>
<div id="console"></div>
<script>
"use strict";
description("Verifies behavior of deleted objects");
const wtu = WebGLTestUtils;
const canvas1 = document.getElementById("canvas1");
const sz = 64;
canvas1.width = sz;
canvas1.height = sz;
const gl = wtu.create3DContext("canvas1");
let tex, rb; // for shouldBe
function testBoundFBOTexture() {
debug("Verifies that a texture attached to a bound framebuffer and then deleted is automatically detached");
let fb = gl.createFramebuffer();
gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
tex = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, tex);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, sz, sz, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex, 0);
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no errors during framebuffer setup");
// The WebGL 1.0 spec guarantees that this combination of attachments results
// in a complete framebuffer.
shouldBe("gl.checkFramebufferStatus(gl.FRAMEBUFFER)", "gl.FRAMEBUFFER_COMPLETE",
"Framebuffer should be complete after setup");
debug("Texture should still be bound to the context");
shouldBe("gl.getParameter(gl.TEXTURE_BINDING_2D)", "tex");
// Delete the texture.
gl.deleteTexture(tex);
debug("Texture should have been unbound from the context");
shouldBeNull("gl.getParameter(gl.TEXTURE_BINDING_2D)");
debug("Framebuffer should report that the texture was detached");
shouldBe("gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE)", "gl.NONE");
debug("Framebuffer should be incomplete after texture was deleted");
shouldNotBe("gl.checkFramebufferStatus(gl.FRAMEBUFFER)", "gl.FRAMEBUFFER_COMPLETE");
debug("Texture should not report that it's still a texture after deletion");
shouldBe("gl.isTexture(tex)", "false");
// Framebuffer should not function.
gl.clearColor(0.0, 1.0, 0.0, 1.0);
gl.clear(gl.COLOR_BUFFER_BIT);
wtu.glErrorShouldBe(gl, gl.INVALID_FRAMEBUFFER_OPERATION, "Framebuffer should not work after deleting its only attachment");
// Default framebuffer shouldn't have been touched.
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
wtu.checkCanvasRect(gl, 0, 0, sz, sz, [0, 0, 0, 0], "default framebuffer should be transparent black");
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no errors after verifying default framebuffer's contents");
// Attempt to bind deleted texture should fail.
gl.bindTexture(gl.TEXTURE_2D, tex);
wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "from binding deleted texture");
debug("");
gl.deleteFramebuffer(fb);
}
function testUnboundFBOTexture() {
debug("Verifies that a texture attached to an unbound framebuffer and then deleted remains usable until detached");
let fb = gl.createFramebuffer();
gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
tex = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, tex);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, sz, sz, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex, 0);
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no errors during framebuffer setup");
// The WebGL 1.0 spec guarantees that this combination of attachments results
// in a complete framebuffer.
shouldBe("gl.checkFramebufferStatus(gl.FRAMEBUFFER)", "gl.FRAMEBUFFER_COMPLETE",
"Framebuffer should be complete after setup");
// Unbind the framebuffer from the context so that deleting the texture
// doesn't automatically unbind it from the framebuffer.
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
debug("Texture should still be bound to the context");
shouldBe("gl.getParameter(gl.TEXTURE_BINDING_2D)", "tex");
// Delete the texture.
gl.deleteTexture(tex);
debug("Texture should have been unbound from the context");
shouldBeNull("gl.getParameter(gl.TEXTURE_BINDING_2D)");
// Framebuffer should still be complete.
gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
debug("Framebuffer should still be complete after texture was deleted");
shouldBe("gl.checkFramebufferStatus(gl.FRAMEBUFFER)", "gl.FRAMEBUFFER_COMPLETE");
debug("Framebuffer should report that the texture is still attached");
shouldBe("gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME)", "tex");
debug("Texture should not report that it's still a texture after deletion");
shouldBe("gl.isTexture(tex)", "false");
// Framebuffer should still function.
gl.clearColor(0.0, 1.0, 0.0, 1.0);
gl.clear(gl.COLOR_BUFFER_BIT);
wtu.checkCanvasRect(gl, 0, 0, sz, sz, [0, 255, 0, 255], "framebuffer should be green");
// Deleting texture a second time should not unbind it from the framebuffer.
gl.deleteTexture(tex);
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "deleting an object twice is not an error");
debug("Framebuffer should still report that the texture is attached");
shouldBe("gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME)", "tex");
// Default framebuffer shouldn't have been touched.
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
wtu.checkCanvasRect(gl, 0, 0, sz, sz, [0, 0, 0, 0], "default framebuffer should be transparent black");
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no errors after verifying framebuffers' contents");
// Attempt to bind deleted texture should fail.
gl.bindTexture(gl.TEXTURE_2D, tex);
wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "from binding deleted texture");
debug("");
gl.deleteFramebuffer(fb);
}
function testBoundFBORenderbuffer() {
debug("Verifies that a renderbuffer attached to a bound framebuffer and then deleted is automatically detached");
let fb = gl.createFramebuffer();
gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
rb = gl.createRenderbuffer();
gl.bindRenderbuffer(gl.RENDERBUFFER, rb);
gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA4, sz, sz)
gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, rb);
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no errors during framebuffer setup");
// The WebGL 1.0 spec doesn't guarantee that this framebuffer configuration
// will be complete.
if (gl.checkFramebufferStatus(gl.FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE) {
debug("Framebuffer with GL_RGBA4 renderbuffer was incomplete; skipping test");
return;
}
debug("Renderbuffer should still be bound to the context");
shouldBe("gl.getParameter(gl.RENDERBUFFER_BINDING)", "rb");
// Delete the renderbuffer.
gl.deleteRenderbuffer(rb);
debug("Renderbuffer should have been unbound from the context");
shouldBeNull("gl.getParameter(gl.RENDERBUFFER_BINDING)");
debug("Framebuffer should report that the texture was detached");
shouldBe("gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE)", "gl.NONE");
debug("Framebuffer should be incomplete after renderbuffer was deleted");
shouldNotBe("gl.checkFramebufferStatus(gl.FRAMEBUFFER)", "gl.FRAMEBUFFER_COMPLETE");
debug("Renderbuffer should not report that it's still a renderbuffer after deletion");
shouldBe("gl.isRenderbuffer(rb)", "false");
// Framebuffer should not function.
gl.clearColor(0.0, 1.0, 0.0, 1.0);
gl.clear(gl.COLOR_BUFFER_BIT);
wtu.glErrorShouldBe(gl, gl.INVALID_FRAMEBUFFER_OPERATION, "Framebuffer should not work after deleting its only attachment");
// Default framebuffer shouldn't have been touched.
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
wtu.checkCanvasRect(gl, 0, 0, sz, sz, [0, 0, 0, 0], "default framebuffer should be transparent black");
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no errors after verifying framebuffers' contents");
// Attempt to bind deleted renderbuffer should fail.
gl.bindRenderbuffer(gl.RENDERBUFFER, rb);
wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "from binding deleted renderbuffer");
debug("");
gl.deleteFramebuffer(fb);
}
function testUnboundFBORenderbuffer() {
debug("Verifies that a renderbuffer attached to an unbound framebuffer and then deleted remains usable until detached");
let fb = gl.createFramebuffer();
gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
rb = gl.createRenderbuffer();
gl.bindRenderbuffer(gl.RENDERBUFFER, rb);
gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA4, sz, sz)
gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, rb);
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no errors during framebuffer setup");
// The WebGL 1.0 spec doesn't guarantee that this framebuffer configuration
// will be complete.
if (gl.checkFramebufferStatus(gl.FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE) {
debug("Framebuffer with GL_RGBA4 renderbuffer was incomplete; skipping test");
return;
}
// Unbind the framebuffer from the context so that deleting the renderbuffer
// doesn't automatically unbind it from the framebuffer.
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
debug("Renderbuffer should still be bound to the context");
shouldBe("gl.getParameter(gl.RENDERBUFFER_BINDING)", "rb");
// Delete the renderbuffer.
gl.deleteRenderbuffer(rb);
debug("Renderbuffer should have been unbound from the context");
shouldBeNull("gl.getParameter(gl.RENDERBUFFER_BINDING)");
// Framebuffer should still be complete.
gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
debug("Framebuffer should still be complete after renderbuffer was deleted");
shouldBe("gl.checkFramebufferStatus(gl.FRAMEBUFFER)", "gl.FRAMEBUFFER_COMPLETE");
debug("Framebuffer should report that the renderbuffer is still attached");
shouldBe("gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME)", "rb");
debug("Renderbuffer should not report that it's still a renderbuffer after deletion");
shouldBe("gl.isRenderbuffer(rb)", "false");
// Framebuffer should still function.
gl.clearColor(0.0, 1.0, 0.0, 1.0);
gl.clear(gl.COLOR_BUFFER_BIT);
// Use a high tolerance to accommodate low bit depth precision.
wtu.checkCanvasRect(gl, 0, 0, sz, sz, [0, 255, 0, 255], "framebuffer should be green", 20);
// Deleting renderbuffer a second time should not unbind it from the framebuffer.
gl.deleteRenderbuffer(rb);
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "deleting an object twice is not an error");
debug("Framebuffer should still report that the renderbuffer is attached");
shouldBe("gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME)", "rb");
// Default framebuffer shouldn't have been touched.
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
wtu.checkCanvasRect(gl, 0, 0, sz, sz, [0, 0, 0, 0], "default framebuffer should be transparent black");
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no errors after verifying framebuffers' contents");
// Attempt to bind deleted renderbuffer should fail.
gl.bindRenderbuffer(gl.RENDERBUFFER, rb);
wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "from binding deleted renderbuffer");
debug("");
gl.deleteFramebuffer(fb);
}
function runTests() {
testBoundFBOTexture();
testUnboundFBOTexture();
testBoundFBORenderbuffer();
testUnboundFBORenderbuffer();
finishTest();
}
requestAnimationFrame(runTests);
var successfullyParsed = true;
</script>
</body>
</html>

Просмотреть файл

@ -37,6 +37,6 @@ webgl-debug-shaders.html
--min-version 1.0.2 --max-version 1.9.9 webgl-depth-texture.html
--min-version 1.0.3 --max-version 1.9.9 webgl-draw-buffers.html
--min-version 1.0.4 --max-version 1.9.9 webgl-draw-buffers-broadcast-return.html
--min-version 1.0.3 --max-version 1.9.9 webgl-draw-buffers-feedback-loop.html
--min-version 1.0.4 --max-version 1.9.9 webgl-draw-buffers-framebuffer-unsupported.html
--min-version 1.0.4 --max-version 1.9.9 webgl-draw-buffers-max-draw-buffers.html
--min-version 1.0.4 webgl-multi-draw.html

Просмотреть файл

@ -33,21 +33,31 @@
<script src="../../js/js-test-pre.js"></script>
<script src="../../js/webgl-test-utils.js"></script>
<script src="../../js/tests/oes-texture-float-and-half-float-linear.js"></script>
</head>
<body>
<div id="description"></div>
<div id="console"></div>
<script>
"use strict";
function testPrologue(gl, extensionTypeName) {
if (!gl.getExtension(extensionTypeName)) {
testPassed("No " + extensionTypeName + " support -- this is legal");
return false;
description("Test OES_texture_float_linear, if available.");
const wtu = WebGLTestUtils;
const gl = wtu.create3DContext();
(function() {
if (!(gl instanceof WebGL2RenderingContext)) {
if (!gl.getExtension("OES_texture_float")) {
testPassed("No OES_texture_float support -- this is legal");
return;
}
}
testPassed("Successfully enabled " + extensionTypeName + " extension");
return true;
}
testTexLinear(gl, "OES_texture_float_linear", "RGBA32F", "FLOAT");
})();
debug("");
const successfullyParsed = true;
</script>
</head>
<body onload='generateTest("OES_texture_float", "OES_texture_float_linear", "FLOAT", testPrologue)()'>
<div id="description"></div>
<canvas id="canvas" style="width: 50px; height: 50px;"> </canvas>
<div id="console"></div>
<script src="../../js/js-test-post.js"></script>
</body>
</html>

Просмотреть файл

@ -51,7 +51,7 @@ function testPrologue(gl) {
<canvas id="example" width="32" height="32"></canvas>
<div id="description"></div>
<div id="console"></div>
<video width="640" height="228" id="vid" controls>
<video width="640" height="228" id="vid" controls muted>
<source src="../../resources/red-green.mp4" type='video/mp4; codecs="avc1.42E01E, mp4a.40.2"' />
<source src="../../resources/red-green.webmvp8.webm" type='video/webm; codecs="vp8, vorbis"' />
<source src="../../resources/red-green.theora.ogv" type='video/ogg; codecs="theora, vorbis"' />

Просмотреть файл

@ -29,10 +29,11 @@
<html>
<head>
<meta charset="utf-8">
<title>WebGL OES_texture_float Conformance Tests</title>
<title>OES_texture_float/WEBGL_color_buffer_float</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>
<script src="../../js/tests/ext-float-blend.js"></script>
</head>
<body>
<div id="description"></div>
@ -73,7 +74,7 @@ void main()
</script>
<script>
"use strict";
description("This test verifies the functionality of the OES_texture_float extension, if it is available.");
description("This test verifies the functionality of the OES_texture_float and WEBGL_color_buffer_float extensions, if available.");
debug("");
@ -127,6 +128,19 @@ if (!gl) {
runRenderTargetAndReadbackTest(testProgram, gl.RGB, 3, [10000, 10000, 10000, 1], 0, false);
runRenderTargetAndReadbackTest(testProgram, gl.RGBA, 4, [10000, 10000, 10000, 10000], 1, true);
runRenderTargetAndReadbackTest(testProgram, gl.RGBA, 4, [10000, 10000, 10000, 10000], 0.5, true);
runFramebufferTest();
debug("");
debug("Test float32 blending without EXT_float_blend.");
testExtFloatBlend(gl.RGBA);
debug("");
debug("Testing that float32 blending succeeds with EXT_float_blend.");
if (!gl.getExtension("EXT_float_blend")) {
testPassed("No EXT_float_blend support -- this is legal");
return;
}
testExtFloatBlend(gl.RGBA);
}
})();
@ -315,6 +329,114 @@ function runUniqueObjectTest()
shouldBe('gl.getExtension("OES_texture_float").myProperty', '2');
}
// Make sure we can call readPixels with the passed in arrayBufferConstructor and that the color
// channels are the ones we expect. If there is a mismatch between the glType and arrayBuffer type,
// fail the test.
function verifyReadPixelsColors(red, green, blue, alpha, alphaRGB, glFormat, glType, arrayBufferConstructor) {
var typeName = wtu.glEnumToString(gl, glType);
debug(wtu.glEnumToString(gl, glFormat) + " framebuffer with " + typeName + " readback.");
var arrayBuffer = new arrayBufferConstructor(4);
gl.readPixels(0, 0, 1, 1, gl.RGBA, glType, arrayBuffer);
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "readPixels should return NO_ERROR when reading " + typeName + " data.");
assertMsg(arrayBuffer[0] === red, "Red channel should be " + red + " for " + typeName + " readPixels. Received: " + arrayBuffer[0]);
assertMsg(arrayBuffer[1] === green, "Green channel should be " + green + " for " + typeName + " readPixels. Received: " + arrayBuffer[1]);
assertMsg(arrayBuffer[2] === blue, "Blue channel should be " + blue + " for " + typeName + " readPixels. Received: " + arrayBuffer[2]);
if (glFormat === gl.RGBA) {
assertMsg(arrayBuffer[3] === alpha, "Alpha channel should be " + alpha + " for " + typeName + " readPixels. Received: " + arrayBuffer[3]);
} else if (glFormat === gl.RGB) {
assertMsg(arrayBuffer[3] === alphaRGB, "Alpha channel should be " + alphaRGB + " for " + typeName + " readPixels. Received: " + arrayBuffer[3]);
}
// Make sure any arrayBuffer types that are not equal to arrayBufferConstructor fail readPixels.
if (arrayBufferConstructor !== Uint8Array) {
arrayBuffer = new Uint8Array(4);
gl.readPixels(0, 0, 1, 1, gl.RGBA, glType, arrayBuffer);
wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "readPixels should return INVALID_OPERATION when reading mismatched types. " + Uint8Array.toString());
}
if (arrayBufferConstructor !== Float32Array) {
arrayBuffer = new Float32Array(4);
gl.readPixels(0, 0, 1, 1, gl.RGBA, glType, arrayBuffer);
wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "readPixels should return INVALID_OPERATION when reading mismatched types. " + Float32Array.toString());
}
if (arrayBufferConstructor !== Uint16Array) {
arrayBuffer = new Uint16Array(4);
gl.readPixels(0, 0, 1, 1, gl.RGBA, glType, arrayBuffer);
wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "readPixels should return INVALID_OPERATION when reading mismatched types. " + Uint16Array.toString());
}
}
// Verify that float textures attached to frame buffers function correctly with regard to framebuffer
// completness, IMPLEMENTATION_COLOR_READ_FORMAT/TYPE and readPixels
function runFramebufferTest() {
debug("");
debug("Framebuffer Tests");
var texture = allocateTexture();
gl.bindTexture(gl.TEXTURE_2D, texture);
var fbo = gl.createFramebuffer();
gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0);
debug("Ensure non-color-renderable formats [LUMINANCE, LUMINANCE_ALPHA, ALPHA] fail.");
var arrayBufferFloatOutput = new Float32Array(4); // 4 color channels
[gl.LUMINANCE, gl.LUMINANCE_ALPHA, gl.ALPHA].forEach(function(badFormat) {
debug(wtu.glEnumToString(gl, badFormat) + " framebuffer");
gl.texImage2D(gl.TEXTURE_2D, 0, badFormat, 1, 1, 0, badFormat, gl.FLOAT, null);
shouldBe("gl.checkFramebufferStatus(gl.FRAMEBUFFER)", "gl.FRAMEBUFFER_INCOMPLETE_ATTACHMENT");
shouldBeNull("gl.getParameter(gl.IMPLEMENTATION_COLOR_READ_FORMAT)");
wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "IMPLEMENTATION_COLOR_READ_FORMAT should fail for incomplete framebuffers.");
shouldBeNull("gl.getParameter(gl.IMPLEMENTATION_COLOR_READ_TYPE)");
wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "IMPLEMENTATION_COLOR_READ_TYPE should fail for incomplete framebuffers.");
gl.readPixels(0, 0, 1, 1, gl.RGBA, gl.FLOAT, arrayBufferFloatOutput);
wtu.glErrorShouldBe(gl, gl.INVALID_FRAMEBUFFER_OPERATION , "readPixels should fail on incomplete framebuffers.");
debug("");
});
debug("Ensure color renderable formats [RGBA, RGB] succeed.");
var arrayBufferFloatInput = new Float32Array(4); // 4 color channels
arrayBufferFloatInput[0] = 0;
arrayBufferFloatInput[1] = .25;
arrayBufferFloatInput[2] = .50;
arrayBufferFloatInput[3] = .75;
[gl.RGBA, gl.RGB].forEach(function(goodFormat) {
debug("");
debug(wtu.glEnumToString(gl, goodFormat) + " framebuffer tests");
gl.texImage2D(gl.TEXTURE_2D, 0, goodFormat, 1, 1, 0, goodFormat, gl.FLOAT, arrayBufferFloatInput);
if (gl.checkFramebufferStatus(gl.FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE) {
testPassed("Format is not renderable. This is allowed.");
return;
}
verifyReadPixelsColors(
0.00, // red
0.25, // green
0.50, // blue
0.75, // alpha
1.0, // alphaRGB
goodFormat,
gl.FLOAT,
Float32Array);
var implementationColorReadFormat = gl.getParameter(gl.IMPLEMENTATION_COLOR_READ_FORMAT);
assertMsg(implementationColorReadFormat === gl.RGBA || implementationColorReadFormat === gl.RGB,
"IMPLEMENTATION_COLOR_READ_FORMAT should be color renderable: RGBA or RGB. Received: " + wtu.glEnumToString(gl, implementationColorReadFormat));
var implementationColorReadType = gl.getParameter(gl.IMPLEMENTATION_COLOR_READ_TYPE);
assertMsg(implementationColorReadType === gl.UNSIGNED_BYTE ||
implementationColorReadType === gl.FLOAT ||
"IMPLEMENTATION_COLOR_READ_TYPE must be one of UNSIGNED_BYTE or FLOAT " +
"Received: " + wtu.glEnumToString(gl, implementationColorReadType));
});
}
debug("");
var successfullyParsed = true;

Просмотреть файл

@ -33,24 +33,35 @@
<script src="../../js/js-test-pre.js"></script>
<script src="../../js/webgl-test-utils.js"></script>
<script src="../../js/tests/oes-texture-float-and-half-float-linear.js"></script>
</head>
<body>
<div id="description"></div>
<div id="console"></div>
<script>
"use strict";
function testPrologue(gl, extensionTypeName) {
var ext = null;
if (!(ext = gl.getExtension(extensionTypeName))) {
testPassed("No " + extensionTypeName + " support -- this is legal");
return false;
description("Test OES_texture_half_float_linear, if available.");
const wtu = WebGLTestUtils;
const gl = wtu.create3DContext();
(function() {
if (gl instanceof WebGL2RenderingContext)
throw new Error("OES_texture_half_float_linear is core in WebGL 2.");
const ext = gl.getExtension("OES_texture_half_float");
if (!ext) {
testPassed("No OES_texture_half_float support -- this is legal");
return;
}
// Required by the test harness.
gl.HALF_FLOAT_OES = ext.HALF_FLOAT_OES;
testPassed("Successfully enabled " + extensionTypeName + " extension");
return true;
}
testTexLinear(gl, "OES_texture_half_float_linear", undefined, "HALF_FLOAT_OES");
})();
debug("");
const successfullyParsed = true;
</script>
</head>
<body onload='generateTest("OES_texture_half_float", "OES_texture_half_float_linear", "HALF_FLOAT_OES", testPrologue)()'>
<div id="description"></div>
<canvas id="canvas" style="width: 50px; height: 50px;"> </canvas>
<div id="console"></div>
<script src="../../js/js-test-post.js"></script>
</body>
</html>

Просмотреть файл

@ -56,7 +56,7 @@ function testPrologue(gl) {
<canvas id="example" width="32" height="32"></canvas>
<div id="description"></div>
<div id="console"></div>
<video width="640" height="228" id="vid" controls>
<video width="640" height="228" id="vid" controls muted>
<source src="../../resources/red-green.mp4" type='video/mp4; codecs="avc1.42E01E, mp4a.40.2"' />
<source src="../../resources/red-green.webmvp8.webm" type='video/webm; codecs="vp8, vorbis"' />
<source src="../../resources/red-green.theora.ogv" type='video/ogg; codecs="theora, vorbis"' />

Просмотреть файл

@ -224,33 +224,6 @@ function getNumberOfChannels(format)
return 2;
}
function getFormatName(format)
{
if (format == gl.RGBA)
return "RGBA";
else if (format == gl.RGB)
return "RGB";
else if (format == gl.LUMINANCE)
return "LUMINANCE";
else if (format == gl.ALPHA)
return "ALPHA";
else if (format == gl.LUMINANCE_ALPHA)
return "LUMINANCE_ALPHA";
}
function getTypeName(type) {
if (type === gl.UNSIGNED_BYTE)
return "UNSIGNED_BYTE";
else if (type === ext.HALF_FLOAT_OES)
return "HALF_FLOAT_OES";
else if (type === gl.UNSIGNED_SHORT_4_4_4_4)
return "UNSIGNED_SHORT_4_4_4_4";
else if (type === gl.UNSIGNED_SHORT_5_5_5_1)
return "UNSIGNED_SHORT_5_6_5";
else if (type === gl.FLOAT)
return "FLOAT";
}
function allocateTexture()
{
var texture = gl.createTexture();
@ -272,7 +245,7 @@ function runTextureCreationTest(extensionEnabled, opt_format, opt_data, opt_expe
if (!extensionEnabled || !opt_expected)
expectSuccess = false;
debug("Testing texture creation with extension " + (extensionEnabled ? "enabled" : "disabled") +
", format " + getFormatName(format) + ", and data " + (data ? "non-null" : "null") +
", format " + wtu.glEnumToString(gl, format) + ", and data " + (data ? "non-null" : "null") +
". Expect " + (expectSuccess ? "Success" : "Failure"));
var texture = allocateTexture();
@ -386,9 +359,9 @@ function runUniqueObjectTest()
// channels are the ones we expect. If there is a mismatch between the glType and arrayBuffer type,
// fail the test.
function verifyReadPixelsColors(red, green, blue, alpha, alphaRGB, glFormat, glType, arrayBufferConstructor) {
var typeName = getTypeName(glType);
var typeName = wtu.glEnumToString(gl, glType);
debug(getFormatName(glFormat) + " framebuffer with " + typeName + " readback.");
debug(wtu.glEnumToString(gl, glFormat) + " framebuffer with " + typeName + " readback.");
var arrayBuffer = new arrayBufferConstructor(4);
gl.readPixels(0, 0, 1, 1, gl.RGBA, glType, arrayBuffer);
@ -437,7 +410,7 @@ function runFramebufferTest() {
debug("Ensure non-color-renderable formats [LUMINANCE, LUMINANCE_ALPHA, ALPHA] fail.");
var arrayBufferFloatOutput = new Float32Array(4); // 4 color channels
[gl.LUMINANCE, gl.LUMINANCE_ALPHA, gl.ALPHA].forEach(function(badFormat) {
debug(getFormatName(badFormat) + " framebuffer");
debug(wtu.glEnumToString(gl, badFormat) + " framebuffer");
gl.texImage2D(gl.TEXTURE_2D, 0, badFormat, 1, 1, 0, badFormat, ext.HALF_FLOAT_OES, null);
shouldBe("gl.checkFramebufferStatus(gl.FRAMEBUFFER)", "gl.FRAMEBUFFER_INCOMPLETE_ATTACHMENT");
@ -461,7 +434,7 @@ function runFramebufferTest() {
arrayBufferHalfFloatInput[3] = 0x3A00; // 0.75 in half float
[gl.RGBA, gl.RGB].forEach(function(goodFormat) {
debug(getFormatName(goodFormat) + " framebuffer tests");
debug(wtu.glEnumToString(gl, goodFormat) + " framebuffer tests");
debug("");
gl.texImage2D(gl.TEXTURE_2D, 0, goodFormat, 1, 1, 0, goodFormat, ext.HALF_FLOAT_OES, arrayBufferHalfFloatInput);
@ -479,7 +452,7 @@ function runFramebufferTest() {
var implementationColorReadFormat = gl.getParameter(gl.IMPLEMENTATION_COLOR_READ_FORMAT);
assertMsg(implementationColorReadFormat === gl.RGBA || implementationColorReadFormat === gl.RGB,
"IMPLEMENTATION_COLOR_READ_FORMAT should be color renderable: RGBA or RGB. Received: " + getFormatName(implementationColorReadFormat));
"IMPLEMENTATION_COLOR_READ_FORMAT should be color renderable: RGBA or RGB. Received: " + wtu.glEnumToString(gl, implementationColorReadFormat));
var implementationColorReadType = gl.getParameter(gl.IMPLEMENTATION_COLOR_READ_TYPE);
@ -494,7 +467,7 @@ function runFramebufferTest() {
implementationColorReadType === gl.UNSIGNED_SHORT_5_5_5_1 ||
implementationColorReadType === gl.UNSIGNED_SHORT_5_6_5,
"IMPLEMENTATION_COLOR_READ_TYPE must be one of UNSIGNED_BYTE, UNSIGNED_SHORT_4_4_4_4, UNSIGNED_SHORT_5_5_5_1, UNSIGNED_SHORT_5_6_5, FLOAT, or HALF_FLOAT_OES. " +
"Received: " + getTypeName(implementationColorReadType));
"Received: " + wtu.glEnumToString(gl, implementationColorReadType));
// Test the RGBA/HALF_FLOAT_OES combination
if (implementationColorReadFormat === gl.RGBA && implementationColorReadType === ext.HALF_FLOAT_OES) {

Просмотреть файл

@ -1785,8 +1785,8 @@ function testASTCTexture(test, useTexStorage) {
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "allocating compressed texture via texStorage2D");
wtu.clearAndDrawUnitQuad(gl);
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "drawing unit quad");
var clearColor = [0, 0, 0, 0];
wtu.checkCanvas(gl, clearColor, "texture should be initialized to black");
var clearColor = [255, 0, 255, 255];
wtu.checkCanvas(gl, clearColor, "texture should be initialized to error color");
gl.compressedTexSubImage2D(gl.TEXTURE_2D, 0, 0, 0, width, height, format, data);
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "uploading compressed texture data via compressedTexSubImage2D");
} else {

Просмотреть файл

@ -157,6 +157,11 @@ function runTestExtension() {
testDXT1_RGBA();
testDXT3_RGBA();
testDXT5_RGBA();
// Test compressed PBOs with a single format
if (contextVersion >= 2) {
testDXT5_RGBA_PBO();
}
}
function testDXT1_RGB() {
@ -609,6 +614,46 @@ function testDXTTexture(test, useTexStorage) {
}
}
function testDXT5_RGBA_PBO() {
var width = 8;
var height = 8;
var channels = 4;
var data = img_8x8_rgba_dxt5;
var format = ext.COMPRESSED_RGBA_S3TC_DXT5_EXT;
var uncompressedData = uncompressDXT(width, height, data, format);
var tex = gl.createTexture();
// First, PBO size = image size
var pbo1 = gl.createBuffer();
gl.bindBuffer(gl.PIXEL_UNPACK_BUFFER, pbo1);
gl.bufferData(gl.PIXEL_UNPACK_BUFFER, data, gl.STATIC_DRAW);
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "uploading a PBO");
gl.bindTexture(gl.TEXTURE_2D, tex);
gl.texStorage2D(gl.TEXTURE_2D, 1, format, width, height);
gl.compressedTexSubImage2D(gl.TEXTURE_2D, 0, 0, 0, width, height, format, data.length, 0);
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "uploading a texture from a PBO");
gl.bindBuffer(gl.PIXEL_UNPACK_BUFFER, null);
wtu.clearAndDrawUnitQuad(gl);
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "drawing unit quad");
compareRect(width, height, channels, uncompressedData, "NEAREST");
// Second, image is just a subrange of the PBO
var pbo2 = gl.createBuffer();
gl.bindBuffer(gl.PIXEL_UNPACK_BUFFER, pbo2);
gl.bufferData(gl.PIXEL_UNPACK_BUFFER, data.length*3, gl.STATIC_DRAW);
gl.bufferSubData(gl.PIXEL_UNPACK_BUFFER, data.length, data);
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "uploading a PBO subrange");
gl.compressedTexSubImage2D(gl.TEXTURE_2D, 0, 0, 0, width, height, format, data.length, data.length);
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "uploading a texture from a PBO subrange");
gl.bindBuffer(gl.PIXEL_UNPACK_BUFFER, null);
wtu.clearAndDrawUnitQuad(gl);
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "drawing unit quad");
compareRect(width, height, channels, uncompressedData, "NEAREST");
}
function compareRect(width, height, channels, expectedData, filteringMode) {
var actual = new Uint8Array(width * height * 4);
gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, actual);

Просмотреть файл

@ -48,7 +48,7 @@ uniform sampler2D u_texture;
uniform vec2 u_resolution;
void main()
{
vec2 texcoord = gl_FragCoord.xy / u_resolution;
vec2 texcoord = (gl_FragCoord.xy - vec2(0.5)) / (u_resolution - vec2(1.0));
gl_FragColor = texture2D(u_texture, texcoord);
}
</script>
@ -142,7 +142,8 @@ function dumpIt(gl, res, msg) {
function runTestExtension(unpackFlipY) {
debug("Testing WEBGL_depth_texture. UNPACK_FLIP_Y_WEBGL: " + unpackFlipY);
var res = 8;
const res = 2;
const destRes = 4;
// make canvas for testing.
canvas2 = document.createElement("canvas");
@ -154,7 +155,7 @@ function runTestExtension(unpackFlipY) {
var program = wtu.setupProgram(gl, ['vshader', 'fshader'], ['a_position']);
gl.useProgram(program);
gl.uniform2f(gl.getUniformLocation(program, "u_resolution"), res, res);
gl.uniform2f(gl.getUniformLocation(program, "u_resolution"), destRes, destRes);
var buffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
@ -213,6 +214,7 @@ function runTestExtension(unpackFlipY) {
];
for (var jj = 0; jj < filterModes.length; ++jj) {
debug('');
debug('testing ' + filterModes[jj] + ' filtering');
var filterMode = gl[filterModes[jj]];
@ -280,60 +282,101 @@ function runTestExtension(unpackFlipY) {
// use the default texture to render with while we return to the depth texture.
gl.bindTexture(gl.TEXTURE_2D, null);
// render the z-quad
gl.enable(gl.DEPTH_TEST);
gl.clearColor(1, 0, 0, 1);
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
gl.drawArrays(gl.TRIANGLES, 0, 6);
/* Setup 2x2 depth texture:
* 1 0.6 0.8
* |
* 0 0.2 0.4
* 0---1
*/
const d00 = 0.2;
const d01 = 0.4;
const d10 = 0.6;
const d11 = 0.8;
dumpIt(gl, res, "--first--");
gl.enable(gl.SCISSOR_TEST);
gl.scissor(0, 0, 1, 1);
gl.clearDepth(d00);
gl.clear(gl.DEPTH_BUFFER_BIT);
gl.scissor(1, 0, 1, 1);
gl.clearDepth(d10);
gl.clear(gl.DEPTH_BUFFER_BIT);
gl.scissor(0, 1, 1, 1);
gl.clearDepth(d01);
gl.clear(gl.DEPTH_BUFFER_BIT);
gl.scissor(1, 1, 1, 1);
gl.clearDepth(d11);
gl.clear(gl.DEPTH_BUFFER_BIT);
gl.disable(gl.SCISSOR_TEST);
// render the depth texture.
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
gl.canvas.width = destRes;
gl.canvas.height = destRes;
gl.viewport(0, 0, destRes, destRes);
gl.bindTexture(gl.TEXTURE_2D, tex);
gl.clearColor(0, 0, 1, 1);
gl.disable(gl.DITHER);
gl.enable(gl.DEPTH_TEST);
gl.clearColor(1, 0, 0, 1);
gl.clearDepth(1.0);
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
gl.drawArrays(gl.TRIANGLES, 0, 6);
var actualPixels = new Uint8Array(res * res * 4);
gl.readPixels(0, 0, res, res, gl.RGBA, gl.UNSIGNED_BYTE, actualPixels);
dumpIt(gl, res, "--depth--");
// Check that each pixel's R value is less than that of the previous pixel
// in either direction. Basically verify we have a gradient.
var success = true;
for (var yy = 0; yy < res; ++yy) {
for (var xx = 0; xx < res; ++xx) {
var actual = (yy * res + xx) * 4;
var left = actual - 4;
var down = actual - res * 4;
var actualPixels = new Uint8Array(destRes * destRes * 4);
gl.readPixels(0, 0, destRes, destRes, gl.RGBA, gl.UNSIGNED_BYTE, actualPixels);
if (xx > 0) {
if (actualPixels[actual] <= actualPixels[left]) {
testFailed("actual(" + actualPixels[actual] + ") < left(" + actualPixels[left] + ")");
success = false;
}
}
if (yy > 0) {
if (actualPixels[actual] <= actualPixels[down]) {
testFailed("actual(" + actualPixels[actual] + ") < down(" + actualPixels[down] + ")");
success = false;
}
const eps = 0.002;
let expectedMin;
let expectedMax;
if (filterMode == gl.NEAREST) {
expectedMin = [
d00, d00, d10, d10,
d00, d00, d10, d10,
d01, d01, d11, d11,
d01, d01, d11, d11
];
expectedMax = expectedMin.slice();
expectedMin = expectedMin.map(x => x - eps);
expectedMax = expectedMax.map(x => x + eps);
} else {
expectedMin = [
d00-eps, d00, d00, d10-eps,
d00, d00, d00, d10,
d00, d00, d00, d10,
d01-eps, d01, d01, d11-eps,
];
expectedMax = [
d00+eps, d10, d10, d10+eps,
d01, d11, d11, d11,
d01, d11, d11, d11,
d01+eps, d11, d11, d11+eps,
];
}
for (var yy = 0; yy < destRes; ++yy) {
for (var xx = 0; xx < destRes; ++xx) {
const t = xx + destRes*yy;
const was = actualPixels[4*t] / 255.0; // 4bpp
const eMin = expectedMin[t];
const eMax = expectedMax[t];
let func = testPassed;
const text = `At ${xx},${yy}, expected within [${eMin},${eMax}], was ${was.toFixed(3)}`
if (was <= eMin || was >= eMax) {
func = testFailed;
}
func(text);
}
}
// Check that bottom left corner is vastly different thatn top right.
if (actualPixels[(res * res - 1) * 4] - actualPixels[0] < 0xC0) {
testFailed("corners are not different enough");
success = false;
}
if (success) {
testPassed("depth texture rendered correctly.");
}
// check limitations
gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl[typeInfo.attachment], gl.TEXTURE_2D, null, 0);

Просмотреть файл

@ -1,161 +0,0 @@
<!--
/*
** 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">
<title>WebGL Rendering and Sampling Feedback Loop Tests For WEBGL_draw_buffers Extension</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>
<canvas id="example" width="8" height="8"></canvas>
<div id="description"></div>
<div id="console"></div>
<script id="vshader" type="x-shader/x-vertex">
attribute vec4 aPosition;
attribute vec2 aTexCoord;
varying vec2 texCoord;
void main() {
gl_Position = aPosition;
texCoord = aTexCoord;
}
</script>
<script id="fshader" type="x-shader/x-fragment">
#extension GL_EXT_draw_buffers : require
precision mediump float;
uniform sampler2D tex;
varying vec2 texCoord;
void main() {
gl_FragData[0] = texture2D(tex, texCoord);
gl_FragData[1] = texture2D(tex, texCoord);
}
</script>
<script>
"use strict";
var wtu = WebGLTestUtils;
var canvas = document.getElementById("example");
description("This test verifies the functionality of rendering to the same texture where it samples from.");
var gl = wtu.create3DContext(canvas);
var width = 8;
var height = 8;
var tex0;
var tex1;
var fbo;
var ext;
var program;
var positionLoc;
var texCoordLoc;
if (!gl) {
testFailed("WebGL context does not exist");
} else {
testPassed("WebGL context exists");
ext = gl.getExtension("WEBGL_draw_buffers");
if (!ext) {
testPassed("No WEBGL_draw_buffers support -- this is legal");
finishTest();
} else {
testPassed("Successfully enabled WEBGL_draw_buffers extension");
init();
// The sampling texture is bound to COLOR_ATTACHMENT1 during resource allocation
allocate_resource();
rendering_sampling_feedback_loop([gl.NONE, ext.COLOR_ATTACHMENT1_WEBGL], gl.INVALID_OPERATION);
rendering_sampling_feedback_loop([gl.COLOR_ATTACHMENT0, ext.COLOR_ATTACHMENT1_WEBGL], gl.INVALID_OPERATION);
rendering_sampling_feedback_loop([gl.COLOR_ATTACHMENT0, gl.NONE], gl.NO_ERROR);
}
}
function init() {
program = wtu.setupProgram(gl, ['vshader', 'fshader'], ['aPosition', 'aTexCoord'], [0, 1]);
positionLoc = gl.getAttribLocation(program, "aPosition");
texCoordLoc = gl.getAttribLocation(program, "aTexCoord");
if (!program || positionLoc < 0 || texCoordLoc < 0) {
testFailed("Set up program failed");
return;
}
testPassed("Set up program succeeded");
wtu.setupUnitQuad(gl, 0, 1);
gl.viewport(0, 0, width, height);
}
function allocate_resource() {
tex0 = gl.createTexture();
tex1 = gl.createTexture();
fbo = gl.createFramebuffer();
wtu.fillTexture(gl, tex0, width, height, [0xff, 0x0, 0x0, 0xff], 0, gl.RGBA, gl.UNSIGNED_BYTE, gl.RGBA);
wtu.fillTexture(gl, tex1, width, height, [0x0, 0xff, 0x0, 0xff], 0, gl.RGBA, gl.UNSIGNED_BYTE, gl.RGBA);
gl.bindTexture(gl.TEXTURE_2D, tex1);
var texLoc = gl.getUniformLocation(program, "tex");
gl.uniform1i(texLoc, 0);
gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex0, 0);
gl.framebufferTexture2D(gl.FRAMEBUFFER, ext.COLOR_ATTACHMENT1_WEBGL, gl.TEXTURE_2D, tex1, 0);
}
function rendering_sampling_feedback_loop(draw_buffers, error) {
// gl.drawBuffers(draw_buffers);
ext.drawBuffersWEBGL(draw_buffers);
// Make sure framebuffer is complete before feedback loop detection
if (gl.checkFramebufferStatus(gl.FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE) {
testFailed("Framebuffer incomplete.");
return;
}
wtu.clearAndDrawUnitQuad(gl);
wtu.glErrorShouldBe(gl, error, "Rendering to a texture where it samples from should geneates INVALID_OPERATION. Otherwise, it should be NO_ERROR");
}
gl.bindTexture(gl.TEXTURE_2D, null);
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
gl.deleteTexture(tex0);
gl.deleteTexture(tex1);
gl.deleteFramebuffer(fbo);
var successfullyParsed = true;
</script>
<script src="../../js/js-test-post.js"></script>
</body>
</html>

Просмотреть файл

@ -531,7 +531,7 @@ function runDrawTests() {
} else {
gl.useProgram(noWriteProgram);
wtu.drawUnitQuad(gl);
wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "Active draw buffers with missing frag outputs.");
drawBuffersUtils.checkAttachmentsForColor(attachments, [0, 255, 0, 255]);
gl.deleteProgram(noWriteProgram);
}
@ -546,13 +546,11 @@ function runDrawTests() {
debug("test that gl_FragColor does not broadcast unless extension is enabled in fragment shader");
gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
ext.drawBuffersWEBGL([gl.COLOR_ATTACHMENT0]); // While the WG debates whether how to handle this.
ext.drawBuffersWEBGL(bufs);
gl.useProgram(redProgram);
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "there should be no errors");
wtu.drawUnitQuad(gl);
drawBuffersUtils.checkAttachmentsForColorFn(attachments, function(attachment, index) {
return (index == 0) ? [255, 0, 0, 255] : [0, 255, 0, 255];
});
wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "Active draw buffers with missing frag outputs.");
debug("test that gl_FragColor broadcasts if extension is enabled in fragment shader");
gl.clear(gl.COLOR_BUFFER_BIT);

Просмотреть файл

@ -0,0 +1,834 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>WebGL ANGLE_multi_draw Conformance Tests</title>
<link rel="stylesheet" href="../../resources/js-test-style.css"/>
<script src="../../js/desktop-gl-constants.js"></script>
<script src="../../js/js-test-pre.js"></script>
<script src="../../js/webgl-test-utils.js"></script>
</head>
<body>
<script id="vshaderIllegalDrawID" type="x-shader/x-vertex">
attribute vec2 vPosition;
varying vec4 color;
void main()
{
color = vec4(1.0, 0.0, 0.0, 1.0);
gl_Position = vec4(vPosition * 2.0 - 1.0, gl_DrawID, 1);
}
</script>
<script id="vshaderDrawIDZero" type="x-shader/x-vertex">
#extension GL_ANGLE_multi_draw : require
attribute vec2 vPosition;
varying vec4 color;
void main()
{
if (gl_DrawID == 0) {
color = vec4(0, 1, 0, 1);
} else {
color = vec4(1, 0, 0, 1);
}
gl_Position = vec4(vPosition * 2.0 - 1.0, 0, 1);
}
</script>
<!-- The behavior of the shaders below is described in runPixelTests() -->
<script id="vshaderWithDrawID" type="x-shader/x-vertex">
#extension GL_ANGLE_multi_draw : require
attribute vec2 vPosition;
attribute float vInstance;
varying vec4 color;
void main()
{
// color_id = (gl_DrawID / 2) % 3
float quad_id = float(gl_DrawID / 2);
float color_id = quad_id - (3.0 * floor(quad_id / 3.0));
if (color_id < 0.5) {
color = vec4(1, 0, 0, 1);
} else if (color_id < 1.5) {
color = vec4(0, 1, 0, 1);
} else {
color = vec4(0, 0, 1, 1);
}
mat3 transform = mat3(1.0);
// vInstance starts at 1.0 on instanced calls
if (vInstance >= 1.0) {
transform[0][0] = 0.5;
transform[1][1] = 0.5;
}
if (vInstance == 1.0) {
} else if (vInstance == 2.0) {
transform[2][0] = 0.5;
} else if (vInstance == 3.0) {
transform[2][1] = 0.5;
} else if (vInstance == 4.0) {
transform[2][0] = 0.5;
transform[2][1] = 0.5;
}
gl_Position = vec4(transform * vec3(vPosition, 1.0) * 2.0 - 1.0, 1);
}
</script>
<script id="vshaderEmulatedDrawID" type="x-shader/x-vertex">
uniform int drawID;
attribute vec2 vPosition;
attribute float vInstance;
varying vec4 color;
void main()
{
float quad_id = float(drawID / 2);
float color_id = quad_id - (3.0 * floor(quad_id / 3.0));
if (color_id == 0.0) {
color = vec4(1, 0, 0, 1);
} else if (color_id == 1.0) {
color = vec4(0, 1, 0, 1);
} else {
color = vec4(0, 0, 1, 1);
}
mat3 transform = mat3(1.0);
// vInstance starts at 1.0 on instanced calls
if (vInstance >= 1.0) {
transform[0][0] = 0.5;
transform[1][1] = 0.5;
}
if (vInstance == 1.0) {
} else if (vInstance == 2.0) {
transform[2][0] = 0.5;
} else if (vInstance == 3.0) {
transform[2][1] = 0.5;
} else if (vInstance == 4.0) {
transform[2][0] = 0.5;
transform[2][1] = 0.5;
}
gl_Position = vec4(transform * vec3(vPosition, 1.0) * 2.0 - 1.0, 1);
}
</script>
<script id="vshaderNoDrawID" type="x-shader/x-vertex">
attribute vec2 vPosition;
attribute float vInstance;
varying vec4 color;
void main()
{
color = vec4(1.0, 0.0, 0.0, 1.0);
mat3 transform = mat3(1.0);
// vInstance starts at 1.0 on instanced calls
if (vInstance >= 1.0) {
transform[0][0] = 0.5;
transform[1][1] = 0.5;
}
if (vInstance == 1.0) {
} else if (vInstance == 2.0) {
transform[2][0] = 0.5;
} else if (vInstance == 3.0) {
transform[2][1] = 0.5;
} else if (vInstance == 4.0) {
transform[2][0] = 0.5;
transform[2][1] = 0.5;
}
gl_Position = vec4(transform * vec3(vPosition, 1.0) * 2.0 - 1.0, 1);
}
</script>
<script id="fshader" type="x-shader/x-fragment">
precision mediump float;
varying vec4 color;
void main() {
gl_FragColor = color;
}
</script>
<div id="description"></div>
<canvas id="canvas" width="128" height="128"> </canvas>
<div id="console"></div>
<script>
"use strict";
description("This test verifies the functionality of the ANGLE_multi_draw extension, if it is available.");
const wtu = WebGLTestUtils;
const canvas = document.getElementById("canvas");
const gl = wtu.create3DContext(canvas);
const instancedExt = gl && gl.getExtension('ANGLE_instanced_arrays');
// Check if the extension is either both enabled and supported or
// not enabled and not supported.
function runSupportedTest(extensionName, extensionEnabled) {
const supported = gl.getSupportedExtensions();
if (supported.indexOf(extensionName) >= 0) {
if (extensionEnabled) {
testPassed(extensionName + ' listed as supported and getExtension succeeded');
return true;
} else {
testFailed(extensionName + ' listed as supported but getExtension failed');
}
} else {
if (extensionEnabled) {
testFailed(extensionName + ' not listed as supported but getExtension succeeded');
} else {
testPassed(extensionName + ' not listed as supported and getExtension failed -- this is legal');
}
}
return false;
}
function runTest() {
if (!gl) {
return function() {
testFailed('WebGL context does not exist');
}
}
doTest('WEBGL_multi_draw', false);
doTest('WEBGL_multi_draw_instanced', true);
}
function doTest(extensionName, instanced) {
const ext = gl.getExtension(extensionName);
if (!runSupportedTest(extensionName, ext)) {
return;
}
function runValidationTests() {
const vertexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([ 0.2,0.2, 0.8,0.2, 0.5,0.8 ]), gl.STATIC_DRAW);
const indexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint8Array([ 0, 1, 2, 0]), gl.STATIC_DRAW);
const instanceBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, instanceBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([ 0, 1, 2, 3 ]), gl.STATIC_DRAW);
const program = wtu.setupProgram(gl, ["vshaderNoDrawID", "fshader"], ["vPosition", "vInstance"], [0, 1]);
expectTrue(program != null, "can compile simple program");
function setupDrawArrays() {
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
gl.enableVertexAttribArray(0);
gl.vertexAttribPointer(0, 2, gl.FLOAT, false, 0, 0);
}
function setupDrawElements() {
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
gl.enableVertexAttribArray(0);
gl.vertexAttribPointer(0, 2, gl.FLOAT, false, 0, 0);
}
function setupInstanced() {
gl.bindBuffer(gl.ARRAY_BUFFER, instanceBuffer);
gl.enableVertexAttribArray(1);
gl.vertexAttribPointer(1, 1, gl.FLOAT, false, 0, 0);
if (wtu.getDefault3DContextVersion() < 2) {
instancedExt.vertexAttribDivisorANGLE(1, 1);
} else {
gl.vertexAttribDivisor(1, 1);
}
}
function setupDrawArraysInstanced() {
setupDrawArrays();
setupInstanced();
}
function setupDrawElementsInstanced() {
setupDrawElements();
setupInstanced();
}
// Wrap a draw call in a function to setup the draw call, execute,
// and check errors.
// The `drawFunc` is one of the extension entrypoints being tested. It may
// be undefined if that entrypoint is not supported on the context
function makeDrawCheck(drawFunc, setup) {
if (!drawFunc) {
return function() {};
}
return function(f_args, expect, msg) {
setup();
drawFunc.apply(ext, f_args);
wtu.glErrorShouldBe(gl, expect, drawFunc.name + " " + msg);
gl.disableVertexAttribArray(0);
gl.disableVertexAttribArray(1);
}
}
const checkMultiDrawArrays = makeDrawCheck(
ext.multiDrawArraysWEBGL, setupDrawArrays);
const checkMultiDrawElements = makeDrawCheck(
ext.multiDrawElementsWEBGL, setupDrawElements);
const checkMultiDrawArraysInstanced = makeDrawCheck(
ext.multiDrawArraysInstancedWEBGL, setupDrawArraysInstanced);
const checkMultiDrawElementsInstanced = makeDrawCheck(
ext.multiDrawElementsInstancedWEBGL, setupDrawElementsInstanced);
gl.useProgram(program);
// Check that drawing a single triangle works
if (!instanced) {
checkMultiDrawArrays(
[gl.TRIANGLES, [0], 0, [3], 0, 1],
gl.NO_ERROR, "with gl.TRIANGLES");
checkMultiDrawElements(
[gl.TRIANGLES, [3], 0, gl.UNSIGNED_BYTE, [0], 0, 1],
gl.NO_ERROR, "with gl.TRIANGLES");
} else {
checkMultiDrawElementsInstanced(
[gl.TRIANGLES, [3], 0, gl.UNSIGNED_BYTE, [0], 0, [1], 0, 1],
gl.NO_ERROR, "with gl.TRIANGLES");
checkMultiDrawArraysInstanced(
[gl.TRIANGLES, [0], 0, [3], 0, [1], 0, 1],
gl.NO_ERROR, "with gl.TRIANGLES");
}
// Zero drawcount permitted
if (!instanced) {
checkMultiDrawArrays(
[gl.TRIANGLES, [0], 0, [3], 0, 0],
gl.NO_ERROR, "with drawcount == 0");
checkMultiDrawElements(
[gl.TRIANGLES, [3], 0, gl.UNSIGNED_BYTE, [0], 0, 0],
gl.NO_ERROR, "with drawcount == 0");
} else {
checkMultiDrawElementsInstanced(
[gl.TRIANGLES, [3], 0, gl.UNSIGNED_BYTE, [0], 0, [1], 0, 0],
gl.NO_ERROR, "with drawcount == 0");
checkMultiDrawArraysInstanced(
[gl.TRIANGLES, [0], 0, [3], 0, [1], 0, 0],
gl.NO_ERROR, "with drawcount == 0");
}
// Check negative drawcount
if (!instanced) {
checkMultiDrawArrays(
[gl.TRIANGLES, [0], 0, [3], 0, -1],
gl.INVALID_VALUE, "with drawcount < 0");
checkMultiDrawElements(
[gl.TRIANGLES, [3], 0, gl.UNSIGNED_BYTE, [0], 0, -1],
gl.INVALID_VALUE, "with drawcount < 0");
} else {
checkMultiDrawElementsInstanced(
[gl.TRIANGLES, [3], 0, gl.UNSIGNED_BYTE, [0], 0, [1], 0, -1],
gl.INVALID_VALUE, "with drawcount < 0");
checkMultiDrawArraysInstanced(
[gl.TRIANGLES, [0], 0, [3], 0, [1], 0, -1],
gl.INVALID_VALUE, "with drawcount < 0");
}
// Check offsets greater than array length
if (!instanced) {
checkMultiDrawArrays(
[gl.TRIANGLES, [0], 1, [3], 0, 1],
gl.INVALID_OPERATION, "with firstsStart >= firstsList.length");
checkMultiDrawArrays(
[gl.TRIANGLES, [0], 0, [3], 1, 1],
gl.INVALID_OPERATION, "with countsStart >= countsList.length");
checkMultiDrawElements(
[gl.TRIANGLES, [3], 1, gl.UNSIGNED_BYTE, [0], 0, 1],
gl.INVALID_OPERATION, "with countsStart >= countsList.length");
checkMultiDrawElements(
[gl.TRIANGLES, [3], 0, gl.UNSIGNED_BYTE, [0], 1, 1],
gl.INVALID_OPERATION, "with offsetsStart >= offsetsList.length");
} else {
checkMultiDrawArraysInstanced(
[gl.TRIANGLES, [0], 1, [3], 0, [1], 0, 1],
gl.INVALID_OPERATION, "with firstsStart >= firstsList.length");
checkMultiDrawArraysInstanced(
[gl.TRIANGLES, [0], 0, [3], 1, [1], 0, 1],
gl.INVALID_OPERATION, "with countsStart >= countsList.length");
checkMultiDrawArraysInstanced(
[gl.TRIANGLES, [0], 0, [3], 0, [1], 1, 1],
gl.INVALID_OPERATION, "with instanceCountsStart >= instanceCountsList.length");
checkMultiDrawElementsInstanced(
[gl.TRIANGLES, [3], 1, gl.UNSIGNED_BYTE, [0], 0, [1], 0, 1],
gl.INVALID_OPERATION, "with countsStart >= countsList.length");
checkMultiDrawElementsInstanced(
[gl.TRIANGLES, [3], 0, gl.UNSIGNED_BYTE, [0], 1, [1], 0, 1],
gl.INVALID_OPERATION, "with offsetsStart >= offsetsList.length");
checkMultiDrawElementsInstanced(
[gl.TRIANGLES, [3], 0, gl.UNSIGNED_BYTE, [0], 0, [1], 1, 1],
gl.INVALID_OPERATION, "with instanceCountsStart >= instanceCountsList.length");
}
}
function runShaderTests() {
const illegalProgram = wtu.setupProgram(gl, ["vshaderIllegalDrawID", "fshader"], ["vPosition"], [0]);
expectTrue(illegalProgram == null, "cannot compile program with gl_DrawID but no extension directive");
const drawIDProgram = wtu.setupProgram(gl, ["vshaderDrawIDZero", "fshader"], ["vPosition"], [0]);
wtu.setupProgram(gl, ["vshaderDrawIDZero", "fshader"], ["vPosition"], [0]);
expectTrue(drawIDProgram !== null, "can compile program with gl_DrawID");
gl.useProgram(drawIDProgram);
gl.bindBuffer(gl.ARRAY_BUFFER, gl.createBuffer());
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([ 0,0, 1,0, 0,1, 0,1, 1,0, 1,1 ]), gl.STATIC_DRAW);
gl.enableVertexAttribArray(0);
gl.vertexAttribPointer(0, 2, gl.FLOAT, false, 0, 0);
gl.drawArrays(gl.TRIANGLES, 0, 6);
wtu.checkCanvas(gl, [0, 255, 0, 255], "gl_DrawID is 0 for non-Multi* draw calls", 0);
}
function runPixelTests() {
// An array of quads is tiled across the screen.
// gl_DrawID is checked by using it to select the color of the draw.
// Instanced entrypoints are tested here scaling and then instancing the
// array of quads over four quadrants on the screen.
// These tests also include "manyDraw" tests which emulate a multiDraw with
// a Javascript for-loop and gl_DrawID with a uniform constiable. They are
// included to ensure the test is written correctly.
const width = gl.canvas.width;
const height = gl.canvas.height;
const x_count = 8;
const y_count = 8;
const quad_count = x_count * y_count;
const tri_count = quad_count * 2;
const tileSize = [ 1/x_count, 1/y_count ];
const tilePixelSize = [ Math.floor(width / x_count), Math.floor(height / y_count) ];
const quadRadius = [ 0.25 * tileSize[0], 0.25 * tileSize[1] ];
const pixelCheckSize = [ Math.floor(quadRadius[0] * width), Math.floor(quadRadius[1] * height) ];
function getTileCenter(x, y) {
return [ tileSize[0] * (0.5 + x), tileSize[1] * (0.5 + y) ];
}
function getQuadVertices(x, y) {
const center = getTileCenter(x, y);
return [
[center[0] - quadRadius[0], center[1] - quadRadius[1], 0],
[center[0] + quadRadius[0], center[1] - quadRadius[1], 0],
[center[0] + quadRadius[0], center[1] + quadRadius[1], 0],
[center[0] - quadRadius[0], center[1] + quadRadius[1], 0],
]
}
const indicesData = [];
const verticesData = [];
const nonIndexedVerticesData = [];
{
const is = new Uint16Array([0, 1, 2, 0, 2, 3]);
for (let y = 0; y < y_count; ++y) {
for (let x = 0; x < x_count; ++x) {
const quadIndex = y * x_count + x;
const starting_index = 4 * quadIndex;
const vs = getQuadVertices(x, y);
for (let i = 0; i < is.length; ++i) {
indicesData.push(starting_index + is[i]);
}
for (let i = 0; i < vs.length; ++i) {
for (let v = 0; v < vs[i].length; ++v) verticesData.push(vs[i][v]);
}
for (let i = 0; i < is.length; ++i) {
for (let v = 0; v < vs[is[i]].length; ++v) nonIndexedVerticesData.push(vs[is[i]][v]);
}
}
}
}
const indices = new Uint16Array(indicesData);
const vertices = new Float32Array(verticesData);
const nonIndexedVertices = new Float32Array(nonIndexedVerticesData);
const indexBuffer = gl.createBuffer();
const vertexBuffer = gl.createBuffer();
const nonIndexedVertexBuffer = gl.createBuffer();
const instanceBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, nonIndexedVertexBuffer);
gl.bufferData(gl.ARRAY_BUFFER, nonIndexedVertices, gl.STATIC_DRAW);
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indices, gl.STATIC_DRAW);
gl.bindBuffer(gl.ARRAY_BUFFER, instanceBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([1, 2, 3, 4]), gl.STATIC_DRAW);
function checkResult(config, msg) {
const rects = [];
const expected = [
[255, 0, 0, 255],
[0, 255, 0, 255],
[0, 0, 255, 255],
];
for (let y = 0; y < y_count; ++y) {
for (let x = 0; x < x_count; ++x) {
const center_x = x * tilePixelSize[0] + Math.floor(tilePixelSize[0] / 2);
const center_y = y * tilePixelSize[1] + Math.floor(tilePixelSize[1] / 2);
const quadID = y * x_count + x;
const colorID = config.drawID ? quadID % 3 : 0;
if (config.instanced) {
rects.push(wtu.makeCheckRect(
center_x / 2 - Math.floor(pixelCheckSize[0] / 4),
center_y / 2 - Math.floor(pixelCheckSize[1] / 4),
pixelCheckSize[0] / 2,
pixelCheckSize[1] / 2,
expected[colorID],
msg + " (" + x + "," + y + ")", 0));
rects.push(wtu.makeCheckRect(
center_x / 2 - Math.floor(pixelCheckSize[0] / 4) + width / 2,
center_y / 2 - Math.floor(pixelCheckSize[1] / 4),
pixelCheckSize[0] / 2,
pixelCheckSize[1] / 2,
expected[colorID],
msg + " (" + x + "," + y + ")", 0));
rects.push(wtu.makeCheckRect(
center_x / 2 - Math.floor(pixelCheckSize[0] / 4),
center_y / 2 - Math.floor(pixelCheckSize[1] / 4) + height / 2,
pixelCheckSize[0] / 2,
pixelCheckSize[1] / 2,
expected[colorID],
msg + " (" + x + "," + y + ")", 0));
rects.push(wtu.makeCheckRect(
center_x / 2 - Math.floor(pixelCheckSize[0] / 4) + width / 2,
center_y / 2 - Math.floor(pixelCheckSize[1] / 4) + height / 2,
pixelCheckSize[0] / 2,
pixelCheckSize[1] / 2,
expected[colorID],
msg + " (" + x + "," + y + ")", 0));
} else {
rects.push(wtu.makeCheckRect(
center_x - Math.floor(pixelCheckSize[0] / 2),
center_y - Math.floor(pixelCheckSize[1] / 2),
pixelCheckSize[0],
pixelCheckSize[1],
expected[colorID],
msg + " (" + x + "," + y + ")", 0));
}
}
}
wtu.checkCanvasRects(gl, rects);
}
const firsts = new Uint32Array(tri_count);
const counts = new Uint32Array(tri_count);
const offsets = new Uint32Array(tri_count);
const instances = new Uint32Array(tri_count);
for (let i = 0; i < firsts.length; ++i) firsts[i] = i * 3;
counts.fill(3);
for (let i = 0; i < offsets.length; ++i) offsets[i] = i * 3 * 2;
instances.fill(4);
const firstsOffset = 47;
const countsOffset = firstsOffset + firsts.length;
const offsetsOffset = countsOffset + counts.length;
const instancesOffset = offsetsOffset + instances.length;
const buffer = new Uint32Array(firstsOffset + firsts.length + counts.length + offsets.length + instances.length);
buffer.set(firsts, firstsOffset);
buffer.set(counts, countsOffset);
buffer.set(offsets, offsetsOffset);
buffer.set(instances, instancesOffset);
let drawIDLocation;
const multiDrawArrays = function() {
ext.multiDrawArraysWEBGL(gl.TRIANGLES, firsts, 0, counts, 0, tri_count);
}
const multiDrawArraysWithNonzeroOffsets = function() {
ext.multiDrawArraysWEBGL(gl.TRIANGLES, buffer, firstsOffset, buffer, countsOffset, tri_count);
}
const multiDrawElements = function() {
ext.multiDrawElementsWEBGL(gl.TRIANGLES, counts, 0, gl.UNSIGNED_SHORT, offsets, 0, tri_count);
}
const multiDrawElementsWithNonzeroOffsets = function() {
ext.multiDrawElementsWEBGL(gl.TRIANGLES, buffer, countsOffset, gl.UNSIGNED_SHORT, buffer, offsetsOffset, tri_count);
}
const multiDrawArraysInstanced = function() {
ext.multiDrawArraysInstancedWEBGL(gl.TRIANGLES, firsts, 0, counts, 0, instances, 0, tri_count);
}
const multiDrawArraysInstancedWithNonzeroOffsets = function() {
ext.multiDrawArraysInstancedWEBGL(gl.TRIANGLES, buffer, firstsOffset, buffer, countsOffset, buffer, instancesOffset, tri_count);
}
const multiDrawElementsInstanced = function() {
ext.multiDrawElementsInstancedWEBGL(gl.TRIANGLES, counts, 0, gl.UNSIGNED_SHORT, offsets, 0, instances, 0, tri_count);
}
const multiDrawElementsInstancedWithNonzeroOffsets = function() {
ext.multiDrawElementsInstancedWEBGL(gl.TRIANGLES, buffer, countsOffset, gl.UNSIGNED_SHORT, buffer, offsetsOffset, buffer, instancesOffset, tri_count);
}
const manyDrawArrays = function() {
for (let i = 0; i < tri_count; ++i) {
gl.drawArrays(gl.TRIANGLES, firsts[i], counts[i]);
}
}
const manyDrawElements = function() {
for (let i = 0; i < tri_count; ++i) {
gl.drawElements(gl.TRIANGLES, counts[i], gl.UNSIGNED_SHORT, offsets[i]);
}
}
const manyDrawArraysEmulateDrawID = function() {
for (let i = 0; i < tri_count; ++i) {
gl.uniform1i(drawIDLocation, i);
gl.drawArrays(gl.TRIANGLES, firsts[i], counts[i]);
}
}
const manyDrawElementsEmulateDrawID = function() {
for (let i = 0; i < tri_count; ++i) {
gl.uniform1i(drawIDLocation, i);
gl.drawElements(gl.TRIANGLES, counts[i], gl.UNSIGNED_SHORT, offsets[i]);
}
}
function drawArraysInstanced() {
if (wtu.getDefault3DContextVersion() < 2) {
instancedExt.drawArraysInstancedANGLE.apply(instancedExt, arguments);
} else {
gl.drawArraysInstanced.apply(gl, arguments);
}
}
function drawElementsInstanced() {
if (wtu.getDefault3DContextVersion() < 2) {
instancedExt.drawElementsInstancedANGLE.apply(instancedExt, arguments);
} else {
gl.drawElementsInstanced.apply(gl, arguments);
}
}
function vertexAttribDivisor(attrib, divisor) {
if (wtu.getDefault3DContextVersion() < 2) {
instancedExt.vertexAttribDivisorANGLE(attrib, divisor);
} else {
gl.vertexAttribDivisor(attrib, divisor);
}
}
const manyDrawArraysInstanced = function() {
for (let i = 0; i < tri_count; ++i) {
drawArraysInstanced(gl.TRIANGLES, firsts[i], counts[i], 4);
}
}
const manyDrawElementsInstanced = function() {
for (let i = 0; i < tri_count; ++i) {
drawElementsInstanced(gl.TRIANGLES, counts[i], gl.UNSIGNED_SHORT, offsets[i], 4);
}
}
const manyDrawArraysInstancedEmulateDrawID = function() {
for (let i = 0; i < tri_count; ++i) {
gl.uniform1i(drawIDLocation, i);
drawArraysInstanced(gl.TRIANGLES, firsts[i], counts[i], 4);
}
}
const manyDrawElementsInstancedEmulateDrawID = function() {
for (let i = 0; i < tri_count; ++i) {
gl.uniform1i(drawIDLocation, i);
drawElementsInstanced(gl.TRIANGLES, counts[i], gl.UNSIGNED_SHORT, offsets[i], 4);
}
}
function checkDraw(config) {
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
if (config.indexed) {
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
gl.enableVertexAttribArray(0);
gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 0, 0);
} else {
gl.bindBuffer(gl.ARRAY_BUFFER, nonIndexedVertexBuffer);
gl.enableVertexAttribArray(0);
gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 0, 0);
}
if (config.instanced) {
gl.bindBuffer(gl.ARRAY_BUFFER, instanceBuffer);
gl.enableVertexAttribArray(1);
gl.vertexAttribPointer(1, 1, gl.FLOAT, false, 0, 0);
vertexAttribDivisor(1, 1);
}
config.drawFunc();
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "there should be no errors");
checkResult(config, config.drawFunc.name + (
config.instanced ? ' instanced' : ''
) + (
config.drawID ? ' with gl_DrawID' : ''
));
gl.disableVertexAttribArray(0);
gl.disableVertexAttribArray(1);
}
const noDrawIDProgram = wtu.setupProgram(gl, ["vshaderNoDrawID", "fshader"], ["vPosition", "vInstance"], [0, 1]);
expectTrue(noDrawIDProgram != null, "can compile simple program");
if (noDrawIDProgram) {
gl.useProgram(noDrawIDProgram);
if (!instanced) {
checkDraw({
drawFunc: multiDrawArrays,
drawID: false,
});
checkDraw({
drawFunc: multiDrawArraysWithNonzeroOffsets,
drawID: false,
});
checkDraw({
drawFunc: multiDrawElements,
indexed: true,
drawID: false,
});
checkDraw({
drawFunc: multiDrawElementsWithNonzeroOffsets,
indexed: true,
drawID: false,
});
checkDraw({
drawFunc: manyDrawArrays,
drawID: false,
});
checkDraw({
drawFunc: manyDrawElements,
indexed: true,
drawID: false,
});
} else {
checkDraw({
drawFunc: multiDrawArraysInstanced,
drawID: false,
instanced: true,
});
checkDraw({
drawFunc: multiDrawArraysInstancedWithNonzeroOffsets,
drawID: false,
instanced: true,
});
checkDraw({
drawFunc: multiDrawElementsInstanced,
indexed: true,
drawID: false,
instanced: true,
});
checkDraw({
drawFunc: multiDrawElementsInstancedWithNonzeroOffsets,
indexed: true,
drawID: false,
instanced: true,
});
checkDraw({
drawFunc: manyDrawArraysInstanced,
drawID: false,
instanced: true,
});
checkDraw({
drawFunc: manyDrawElementsInstanced,
indexed: true,
drawID: false,
instanced: true,
});
}
}
const withDrawIDProgram = wtu.setupProgram(gl, ["vshaderWithDrawID", "fshader"], ["vPosition", "vInstance"], [0, 1]);
expectTrue(withDrawIDProgram != null, "can compile program with ANGLE_multi_draw");
if (withDrawIDProgram) {
gl.useProgram(withDrawIDProgram);
if (!instanced) {
checkDraw({
drawFunc: multiDrawArrays,
drawID: true,
});
checkDraw({
drawFunc: multiDrawArraysWithNonzeroOffsets,
drawID: true,
});
checkDraw({
drawFunc: multiDrawElements,
indexed: true,
drawID: true,
});
checkDraw({
drawFunc: multiDrawElementsWithNonzeroOffsets,
indexed: true,
drawID: true,
});
} else {
checkDraw({
drawFunc: multiDrawArraysInstanced,
drawID: true,
instanced: true,
});
checkDraw({
drawFunc: multiDrawArraysInstancedWithNonzeroOffsets,
drawID: true,
instanced: true,
});
checkDraw({
drawFunc: multiDrawElementsInstanced,
indexed: true,
drawID: true,
instanced: true,
});
checkDraw({
drawFunc: multiDrawElementsInstancedWithNonzeroOffsets,
indexed: true,
drawID: true,
instanced: true,
});
}
}
const emulatedDrawIDProgram = wtu.setupProgram(gl, ["vshaderEmulatedDrawID", "fshader"], ["vPosition", "vInstance"], [0, 1]);
expectTrue(emulatedDrawIDProgram != null, "can compile program to emulate gl_DrawID");
drawIDLocation = gl.getUniformLocation(emulatedDrawIDProgram, "drawID");
if (emulatedDrawIDProgram) {
gl.useProgram(emulatedDrawIDProgram);
if (!instanced) {
checkDraw({
drawFunc: manyDrawArraysEmulateDrawID,
drawID: true,
});
checkDraw({
drawFunc: manyDrawElementsEmulateDrawID,
indexed: true,
drawID: true,
});
} else {
checkDraw({
drawFunc: manyDrawArraysInstancedEmulateDrawID,
drawID: true,
instanced: true,
});
checkDraw({
drawFunc: manyDrawElementsInstancedEmulateDrawID,
indexed: true,
drawID: true,
instanced: true,
});
}
}
}
runValidationTests();
runShaderTests();
runPixelTests();
}
runTest();
const successfullyParsed = true;
</script>
<script src="../../js/js-test-post.js"></script>
</body>
</html>

Просмотреть файл

@ -39,7 +39,7 @@
<canvas id="example" width="256" height="256" style="width: 16px; height: 16px;"></canvas>
<div id="description"></div>
<div id="console"></div>
<script id="vshader2d0" type="x-shader/x-vertex">
<script id="vshader2dvec3" type="x-shader/x-vertex">
attribute vec4 vPosition;
varying vec4 color;
uniform sampler2D tex;
@ -50,7 +50,7 @@ void main() {
color = texture2DProjLod(tex, vec3(0.75 * divisor, 0.25 * divisor, divisor), lod);
}
</script>
<script id="vshader2d1" type="x-shader/x-vertex">
<script id="vshader2dvec4" type="x-shader/x-vertex">
attribute vec4 vPosition;
varying vec4 color;
uniform sampler2D tex;
@ -89,6 +89,8 @@ var colors = [
{name: 'gray', color:[128, 128, 128, 255]},
{name: 'light green', color:[128, 255, 128, 255]},
];
var contextTypes = ["2d", "webgl"];
var vectorTypes = ["vec3", "vec4"];
var gl = wtu.create3DContext(canvas);
if (gl.getParameter(gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS) > 0) {
@ -97,58 +99,78 @@ if (gl.getParameter(gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS) > 0) {
testPassed("MAX_VERTEX_TEXTURE_IMAGE_UNITS == 0, this is okay.");
}
function runTest() {
// Avoid creating a WebGL context for every test, as it causes:
// Too many active WebGL contexts. Oldest context will be lost.
var canvasWebGL = document.createElement("canvas");
var ctxWebGL = canvasWebGL.getContext("webgl");
// Might as well do the same for canvas 2d
var canvas2d = document.createElement("canvas");
var ctx2d = canvas2d.getContext("2d");
shouldBe("colors.length", "9");
for (var ss = 0; ss < 2; ++ss) {
debug("");
debug(ss ? "testing vec4 version" : "testing vec3 version");
var program = wtu.setupProgram(
gl, ['vshader2d' + ss, 'fshader2d'], ['vPosition', 'texCoord0'], [0, 1]);
wtu.setupUnitQuad(gl, 0, 1);
contextTypes.forEach((context) => {
vectorTypes.forEach((vectorType) => {
debug("");
debug(`testing ${context} context with ${vectorType} vertex shader`);
var program = wtu.setupProgram(
gl, ['vshader2d' + vectorType, 'fshader2d'], ['vPosition', 'texCoord0'], [0, 1]);
wtu.setupUnitQuad(gl, 0, 1);
var tex = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, tex);
gl.texParameteri(
gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST_MIPMAP_NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT);
var tex = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, tex);
gl.texParameteri(
gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST_MIPMAP_NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT);
// Fill the top right quadrant of each texture level with one of the colors
for (var ii = 0; ii < colors.length; ++ii) {
var color = colors[ii];
var size = Math.pow(2, colors.length - ii - 1);
var c = document.createElement("canvas");
c.width = size;
c.height = size;
var ctx = c.getContext("2d");
ctx.fillStyle = "rgb(0,0,0)";
ctx.fillRect(0, 0, size, size);
ctx.fillStyle = "rgb(" + color.color[0] + "," + color.color[1] + "," + color.color[2] + ")";
ctx.fillRect(size / 2, 0, size / 2, size / 2);
gl.texImage2D(gl.TEXTURE_2D, ii, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, c);
}
var lodLoc = gl.getUniformLocation(program, "lod");
var divLoc = gl.getUniformLocation(program, "divisor");
for (var div = 1; div < 4; ++div) {
for (var ii = 0; ii < colors.length - 1; ++ii) {
gl.uniform1f(lodLoc, ii);
gl.uniform1f(divLoc, div);
var lodColor = colors[ii];
// Fill the top right quadrant of each texture level with one of the colors
for (var ii = 0; ii < colors.length; ++ii) {
var color = colors[ii];
var size = Math.pow(2, colors.length - ii - 1);
wtu.clearAndDrawUnitQuad(gl);
wtu.checkCanvas(
gl, lodColor.color,
"sampling with lod = " + ii +
" divider = " + div +
" should be " + lodColor.name);
if (context === "2d") {
canvas2d.width = size;
canvas2d.height = size;
ctx2d.fillStyle = "rgb(0,0,0)";
ctx2d.fillRect(0, 0, size, size);
ctx2d.fillStyle = "rgb(" + color.color[0] + "," + color.color[1] + "," + color.color[2] + ")";
ctx2d.fillRect(size / 2, 0, size / 2, size / 2);
gl.texImage2D(gl.TEXTURE_2D, ii, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, canvas2d);
} else if (context === "webgl") {
canvasWebGL.width = canvasWebGL.height = size;
ctxWebGL.clearColor(0, 0, 0, 1);
ctxWebGL.clear(gl.COLOR_BUFFER_BIT);
ctxWebGL.enable(gl.SCISSOR_TEST);
ctxWebGL.scissor(size/2, size/2, size/2, size/2)
ctxWebGL.clearColor(color.color[0]/255, color.color[1]/255, color.color[2]/255, 1)
ctxWebGL.clear(gl.COLOR_BUFFER_BIT);
gl.texImage2D(gl.TEXTURE_2D, ii, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, canvasWebGL);
}
}
}
}
var lodLoc = gl.getUniformLocation(program, "lod");
var divLoc = gl.getUniformLocation(program, "divisor");
for (var div = 1; div < 4; ++div) {
for (var ii = 0; ii < colors.length - 1; ++ii) {
gl.uniform1f(lodLoc, ii);
gl.uniform1f(divLoc, div);
var lodColor = colors[ii];
var size = Math.pow(2, colors.length - ii - 1);
wtu.clearAndDrawUnitQuad(gl);
wtu.checkCanvas(
gl, lodColor.color,
"sampling with lod = " + ii +
" divider = " + div +
" should be " + lodColor.name);
}
}
});
});
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors.");
}

Просмотреть файл

@ -25,7 +25,6 @@ functions/copyTexSubImage2D.html
functions/copyTexSubImage2DBadArgs.html
functions/deleteBufferBadArgs.html
functions/drawArrays.html
functions/drawArraysOutOfBounds.html
functions/drawElements.html
functions/isTests.html
--min-version 1.0.2 functions/isTestsBadArgs.html
@ -51,7 +50,5 @@ functions/vertexAttribBadArgs.html
functions/vertexAttribPointer.html
functions/vertexAttribPointerBadArgs.html
glsl/arrayOutOfBounds.html
#glsl/longLoops.html // No interactive tests.
glsl/uniformOutOfBounds.html
#glsl/unusedAttribsUniforms.html // No interactive tests.

Просмотреть файл

@ -359,6 +359,7 @@ randomImage = function(w,h) {
img.getContext('2d').fillRect(0,0,w,h);
} else if (r < 0.5) {
img = document.createElement('video');
img.muted = true;
img.width = w; img.height = h;
} else if (r < 0.75) {
img = document.createElement('img');

Просмотреть файл

@ -1,607 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<!--
/*
** Copyright (c) 2012 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.
*/
-->
<title>OpenGL for the web</title>
<script type="application/javascript" src="../util.js"></script>
<script type="application/javascript">
function log(msg) {
document.getElementById('note').textContent += "\n"+msg;
}
function init(ev) {
var canvas = document.getElementById('canvas');
var gl = getGLContext(canvas);
var shader = new Shader(gl, "ppix-vert", "ppix-frag");
shader.compile();
var fbo = new FBO(gl, canvas.width, canvas.height);
var fbo2 = new FBO(gl, canvas.width, canvas.height);
var fbo3 = new FBO(gl, canvas.width, canvas.height);
var depth = new Shader(gl, "depth-vert", "depth-frag");
var identity = new Filter(gl, "identity-vert", "identity-frag");
var unpremult = new Filter(gl, "identity-vert", "unpremult-frag");
var hblur = new Filter(gl, "identity-vert", "hblur-frag");
var vblur = new Filter(gl, "identity-vert", "vblur-frag");
var hdof = new Filter(gl, "identity-vert", "hdof-frag");
var vdof = new Filter(gl, "identity-vert", "vdof-frag");
redraw(canvas, gl, shader, fbo, fbo2, fbo3, depth, identity, unpremult, hblur, vblur, hdof, vdof);
setInterval(function(){
redraw(canvas, gl, shader, fbo, fbo2, fbo3, depth, identity, unpremult, hblur, vblur, hdof, vdof);
}, 33);
}
function drawCube (gl, shader, angle, axis, x,y,z, s, va, na, ta) {
Matrix.copyMatrix(look, vmat);
Matrix.translate3InPlace(x,y,z,vmat);
Matrix.scale1InPlace(s,vmat);
Matrix.rotateInPlace(angle, axis, vmat);
// Note: we could just use mat3(MVMatrix) as the normal matrix
// as MVMatrix has only rotations, translations and uniform scaling
// <=> MVMatrix is a scaled orthonormal matrix
// hence normalize(mat3(MVMatrix)*v) == normalize(mat3(transpose(inverse(MVMatrix))*v)
//
// But let's do it the hard way to see if Matrix.inverse3x3 works...
Matrix.inverseTo3x3InPlace(vmat, nmat);
Matrix.transpose3x3InPlace(nmat);
shader.uniformMatrix4fv("MVMatrix", vmat);
shader.uniformMatrix3fv("NMatrix", nmat);
var cube = Cube.getCachedVBO(gl);
cube.draw(va, na, ta);
}
var carr = [];
for (var i=0; i<25; i++) {
carr.push([Math.random(), Math.random(), Math.random()]);
}
function drawScene (gl, shader, va, na, ta) {
var ot = new Date().getTime();
var t = ot;
shader.uniformMatrix4fv("PMatrix", pmat);
for (var i=0; i<carr.length; i++){
var c = carr[i];
var f = c[1] < 0.5 ? 1 : -1;
var t = ot;
drawCube(gl, shader,
(t/(f*400*(c[0]+0.5))) % (2*Math.PI), c,
0.45+0.8*c[2],
-0.4+Math.cos((i/carr.length*Math.PI*2)+t/1000),
0.8+Math.sin((i/carr.length*Math.PI*2)+t/1000)*3.2,
0.05 + Math.pow((c[0]+c[1]+c[2])*0.33, 2)*0.3,
va, na, ta);
}
}
var nmat = Matrix.newIdentity3x3();
var vmat = Matrix.newIdentity();
var vmat2 = Matrix.newIdentity();
var pmat = null;
var look = Matrix.lookAt([4,-1,8], [-0.2,0,0], [0,1,0]);
var useDoF = false;
var firstFrame = true;
function redraw(canvas, gl, shader, fbo, fbo2, fbo3, depth, identity, unpremult, hblur, vblur, hdof, vdof) {
var doDoF = useDoF;
gl.viewport(0, 0, canvas.width, canvas.height);
gl.clearColor(0.0, 0.0, 0.0, 0.0);
gl.enable(gl.DEPTH_TEST);
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
fbo.use();
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
shader.use();
var va = shader.attrib("Vertex");
var na = shader.attrib("Normal");
var ta = shader.attrib("Tex");
if (pmat == null)
pmat = Matrix.perspective(30, canvas.width/canvas.height, 1, 100);
shader.uniform4f("MaterialSpecular", 0.95, 0.9, 0.6, 1);
shader.uniform4f("MaterialDiffuse", 0.50, 0.35, 0.35, 1);
shader.uniform4f("MaterialAmbient", 0.0, 0.1, 0.2, 1);
shader.uniform1f("MaterialShininess", 1.5);
shader.uniform4f("GlobalAmbient", 0.1, 0.1, 0.1, 1);
shader.uniform4f("LightPos", 1, 5, 3, 1.0);
shader.uniform4f("LightSpecular", 0.9, 0.9, 0.9, 1);
shader.uniform4f("LightDiffuse", 0.8, 0.8, 0.8, 1);
shader.uniform4f("LightAmbient", 0.0, 0.06, 0.2, 1);
shader.uniform1f("LightConstantAtt", 0.0);
shader.uniform1f("LightLinearAtt", 0.1);
shader.uniform1f("LightQuadraticAtt", 0.0);
drawScene(gl, shader, va, na);
if (doDoF || firstFrame) {
fbo3.use();
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
depth.use();
var dva = depth.attrib("Vertex");
drawScene(gl, depth, dva);
gl.disable(gl.DEPTH_TEST);
gl.activeTexture(gl.TEXTURE1);
gl.bindTexture(gl.TEXTURE_2D, fbo3.texture);
gl.activeTexture(gl.TEXTURE0);
for (var i=0; i<3; i++) {
fbo2.use();
gl.bindTexture(gl.TEXTURE_2D, fbo.texture);
hdof.apply(function(f){
f.uniform1i("Texture", 0);
f.uniform1i("Depth", 1);
f.uniform1f("iter", i);
f.uniform1f("step", 1.0/canvas.width);
});
fbo.use();
gl.bindTexture(gl.TEXTURE_2D, fbo2.texture);
vdof.apply(function(f){
f.uniform1i("Texture", 0);
f.uniform1i("Depth", 1);
f.uniform1f("iter", i);
f.uniform1f("step", 1.0/canvas.width);
});
}
}
firstFrame = false;
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
gl.activeTexture(gl.TEXTURE1);
gl.bindTexture(gl.TEXTURE_2D, null);
gl.activeTexture(gl.TEXTURE0);
gl.bindTexture(gl.TEXTURE_2D, fbo.texture);
// The DoF blur blurs the color from the transparent black background with
// the cubes. To get rid of the border, we can treat it as premultiplied alpha.
// To see the problem, try replacing unpremult with identity.
unpremult.apply(function(f){
f.uniform1i("Texture", 0);
});
}
window.addEventListener("load", init, false);
</script>
<script id="ppix-vert" type="x-shader/x-vertex">
attribute vec3 Vertex;
attribute vec3 Normal;
attribute vec2 Tex;
uniform mat4 PMatrix;
uniform mat4 MVMatrix;
uniform mat3 NMatrix;
uniform vec4 MaterialAmbient;
uniform vec4 MaterialDiffuse;
uniform vec4 LightAmbient;
uniform vec4 LightDiffuse;
uniform vec4 GlobalAmbient;
uniform vec4 LightPos;
varying vec4 diffuse, ambientGlobal, ambient;
varying vec3 normal, lightDir, halfVector;
varying float dist;
void main()
{
vec4 worldPos;
vec3 lightVector;
vec4 v = vec4(Vertex, 1.0);
/* transform vertex normal into world space and normalize */
normal = normalize(NMatrix * Normal);
/* transform vertex into world space and compute the vector
from it to the light */
worldPos = MVMatrix * v;
lightVector = vec3(LightPos - worldPos);
lightDir = normalize(lightVector);
dist = length(lightVector);
/* Half-vector used in Blinn-Phong shading due to computational efficiency */
halfVector = normalize(lightVector - vec3(worldPos));
diffuse = MaterialDiffuse * LightDiffuse;
/* The ambient terms have been separated since one of them */
/* suffers attenuation */
ambient = MaterialAmbient * LightAmbient;
ambientGlobal = GlobalAmbient * MaterialAmbient;
gl_Position = PMatrix * worldPos;
}
</script>
<script id="ppix-frag" type="x-shader/x-fragment">
precision mediump float;
uniform vec4 LightSpecular;
uniform vec4 MaterialSpecular;
uniform float MaterialShininess;
uniform float LightConstantAtt;
uniform float LightLinearAtt;
uniform float LightQuadraticAtt;
varying vec4 diffuse,ambientGlobal, ambient;
varying vec3 normal, lightDir, halfVector;
varying float dist;
void main()
{
vec3 n, halfV, viewV, ldir;
float NdotL, NdotHV;
vec4 color = ambientGlobal;
float att;
n = normalize(normal);
NdotL = max(dot(n, normalize(lightDir)), 0.0);
if (NdotL > 0.0) {
att = 1.0 / (LightConstantAtt + LightLinearAtt * dist + LightQuadraticAtt * dist * dist);
color += att * (diffuse * NdotL + ambient);
halfV = normalize(halfVector);
NdotHV = max( dot(normal, halfV), 0.0 );
color += att * MaterialSpecular * LightSpecular * pow(NdotHV, MaterialShininess);
}
gl_FragColor = color;
}
</script>
<script id="depth-vert" type="x-shader/x-vertex">
attribute vec3 Vertex;
uniform mat4 PMatrix;
uniform mat4 MVMatrix;
varying float depth;
void main()
{
gl_Position = PMatrix * (MVMatrix * vec4(Vertex, 1.0));
depth = 1.0-(gl_Position.z / gl_Position.w);
}
</script>
<script id="depth-frag" type="x-shader/x-fragment">
precision mediump float;
varying float depth;
void main()
{
vec4 c = vec4(depth, 0.0, 0.0, 1.0);
gl_FragColor = c;
}
</script>
<script id="identity-vert" type="x-shader/x-vertex">
attribute vec3 Vertex;
attribute vec2 Tex;
varying vec4 texCoord0;
void main()
{
texCoord0 = vec4(Tex,0.0,0.0);
gl_Position = vec4(Vertex, 1.0);
}
</script>
<script id="identity-frag" type="x-shader/x-fragment">
precision mediump float;
uniform sampler2D Texture;
varying vec4 texCoord0;
void main()
{
vec4 c = texture2D(Texture, texCoord0.st);
gl_FragColor = c;
}
</script>
<script id="premult-frag" type="x-shader/x-fragment">
precision mediump float;
uniform sampler2D Texture;
varying vec4 texCoord0;
void main()
{
vec4 c = texture2D(Texture, texCoord0.st);
float a = c.a;
c *= a;
c.a = a;
gl_FragColor = c;
}
</script>
<script id="unpremult-frag" type="x-shader/x-fragment">
precision mediump float;
uniform sampler2D Texture;
varying vec4 texCoord0;
void main()
{
vec4 c = texture2D(Texture, texCoord0.st);
float a = c.a;
c /= a;
c.a = a;
gl_FragColor = c;
}
</script>
<script id="hblur-frag" type="x-shader/x-fragment">
precision mediump float;
uniform sampler2D Texture;
uniform float step;
float kernel[7] = float[](0.046, 0.111, 0.202, 0.283, 0.202, 0.111, 0.046);
varying vec4 texCoord0;
void main()
{
int i=0;
if (texture2D(Texture, texCoord0.st).a > 0.0) {
vec4 sum = vec4(0.0);
for (i=0; i<7; i++) {
vec4 tmp = texture2D(Texture, texCoord0.st + vec2(i*step,0));
sum += tmp * kernel[i];
}
gl_FragColor = sum;
} else {
gl_FragColor = texture2D(Texture, texCoord0.st);
}
}
</script>
<script id="vblur-frag" type="x-shader/x-fragment">
precision mediump float;
uniform sampler2D Texture;
uniform float step;
float kernel[7] = float[](0.046, 0.111, 0.202, 0.283, 0.202, 0.111, 0.046);
varying vec4 texCoord0;
void main()
{
int i=0;
if (texture2D(Texture, texCoord0.st).a > 0.0) {
vec4 sum = vec4(0.0);
for (i=0; i<7; i++) {
vec4 tmp = texture2D(Texture, texCoord0.st + vec2(0,i*step));
sum += tmp * kernel[i];
}
gl_FragColor = sum;
} else {
gl_FragColor = texture2D(Texture, texCoord0.st);
}
}
</script>
<script id="hdof-frag" type="x-shader/x-fragment">
precision mediump float;
uniform sampler2D Texture;
uniform sampler2D Depth;
uniform float step;
uniform float iter;
float kernel[7] = { 0.046, 0.111, 0.202, 0.283, 0.202, 0.111, 0.046 };
varying vec4 texCoord0;
void main()
{
vec4 tmp;
vec4 sum = vec4(0.0);
bool b = (iter < -26.0+36.0*(1.0-texture2D(Depth, texCoord0.st).r) && texture2D(Texture, texCoord0.st).a > 0.0);
tmp = texture2D(Texture, texCoord0.st + vec2(float(0-3)*step,0));
sum += tmp * kernel[0];
tmp = texture2D(Texture, texCoord0.st + vec2(float(1-3)*step,0));
sum += tmp * kernel[1];
tmp = texture2D(Texture, texCoord0.st + vec2(float(2-3)*step,0));
sum += tmp * kernel[2];
tmp = texture2D(Texture, texCoord0.st + vec2(float(3-3)*step,0));
sum += tmp * kernel[3];
tmp = texture2D(Texture, texCoord0.st + vec2(float(4-3)*step,0));
sum += tmp * kernel[4];
tmp = texture2D(Texture, texCoord0.st + vec2(float(5-3)*step,0));
sum += tmp * kernel[5];
tmp = texture2D(Texture, texCoord0.st + vec2(float(6-3)*step,0));
sum += tmp * kernel[6];
gl_FragColor = mix(texture2D(Texture, texCoord0.st), sum, b ? 1.0 : 0.0);
}
</script>
<script id="vdof-frag" type="x-shader/x-fragment">
precision mediump float;
uniform sampler2D Texture;
uniform sampler2D Depth;
uniform float step;
uniform float iter;
float kernel[7] = float[7](0.046, 0.111, 0.202, 0.283, 0.202, 0.111, 0.046);
varying vec4 texCoord0;
void main()
{
vec4 tmp;
vec4 sum = vec4(0.0);
bool b = (iter < -26.0+36.0*(1.0-texture2D(Depth, texCoord0.st).r) && texture2D(Texture, texCoord0.st).a > 0.0);
tmp = texture2D(Texture, texCoord0.st + vec2(0,float(0-3)*step));
sum += tmp * kernel[0];
tmp = texture2D(Texture, texCoord0.st + vec2(0,float(1-3)*step));
sum += tmp * kernel[1];
tmp = texture2D(Texture, texCoord0.st + vec2(0,float(2-3)*step));
sum += tmp * kernel[2];
tmp = texture2D(Texture, texCoord0.st + vec2(0,float(3-3)*step));
sum += tmp * kernel[3];
tmp = texture2D(Texture, texCoord0.st + vec2(0,float(4-3)*step));
sum += tmp * kernel[4];
tmp = texture2D(Texture, texCoord0.st + vec2(0,float(5-3)*step));
sum += tmp * kernel[5];
tmp = texture2D(Texture, texCoord0.st + vec2(0,float(6-3)*step));
sum += tmp * kernel[6];
gl_FragColor = mix(texture2D(Texture, texCoord0.st), sum, b ? 1.0 : 0.0);
}
</script>
<style>
* { margin: 0px; padding: 0px; }
html {
background-color: #707888;
color: #222222;
}
#canvas {
position: absolute;
cursor: pointer;
top: 115px; left: 550px;
}
#note {
position: absolute;
top: 4px;
left: 4px;
}
#content {
margin-left: 99px;
padding-left: 8px;
padding-right: 8px;
padding-bottom: 16px;
width: 600px;
background-color: rgba(255,255,255,1.0);
text-align: center;
border-left: 1px solid rgba(0,0,0,0.5);
border-right: 2px solid rgba(0,0,0,0.75);
}
h1 {
padding-top: 24px;
padding-bottom: 16px;
margin-bottom: 24px;
border-bottom: 1px solid black;
font-family: Times New Roman, Serif;
font-weight: bold;
font-size: 40px;
}
#content p {
text-indent: 24px;
margin-left: 24px;
margin-right: 32px;
text-align: justify;
font-family: Serif;
padding-bottom: 16px;
}
#above {
position: absolute;
top: 300px;
left: 716px;
padding: 10px 20px;
background-color: rgba(0,225,0,0.5);
border-left: 2px solid rgba(0,64,0,0.75);
color: white;
font-size: small;
font-family: sans-serif;
}
#above p {
text-align: center;
}
</style>
</head><body>
<canvas id="canvas" width="400" height="400" title="Click to toggle DOF shader" onclick="useDoF = !useDoF"></canvas>
<pre id="note"></pre>
<div id="content">
<h1>OpenGL for the web</h1>
<p>
The WebGL specification gives web developers access to an
OpenGL ES 2.0 drawing context for the canvas tag. What that means is
that you can finally harness the power of the GPU for awesome visuals
and heavy-duty number crunching in your web apps. </p><p> OpenGL ES 2.0 is a subset of OpenGL 2.0 aimed at embedded
devices and game consoles. As such, it's a very minimalistic low-level
API, even more so than desktop OpenGL. In fact, if you took desktop
OpenGL and stripped out everything but shaders, vertex arrays and
textures, you'd get something quite like OpenGL ES 2.0. </p>
<p>
As there is no fixed-function pipeline, you need to write GLSL shaders to draw <i>anything</i>.
And you need to do your own transformation math, including keeping
track of the transformation matrix stack. So the raw API is really not
for the faint of heart; you do need to know your 3D math and shading
equations. </p>
<p> For example, to draw the spinning cubes on the
right - around 200 lines of application code, 250 lines of shaders and
800 lines of library code - I had to scrounge the internet for <a href="http://www.lighthouse3d.com/opengl/glsl/index.php?pointlight">GLSL shaders</a>
to do the transformation and lighting, write a small matrix math
library in JavaScript and a DOF blur shader. While highly educational,
it was also a rather steep hill to climb. </p>
<p> So, the intended audience of the raw context
interface are not really end-users, but library developers who can
write easy-to-use interfaces to the functionality, and 3D developers
who require a high level of control over the rendering pipeline. </p>
<p> The really cool thing about the OpenGL Canvas is
that it doesn't make policy decisions. There's no single set-in-stone
use case for it: In addition to 3D graphics, you can also use it for
filtering images, visualizing fluid dynamics, doing real-time video
effects, or just crunching a whole lot of FP math. If you can do it on
the GPU, you're in luck! </p>
</div>
<div id="above">
<p>You can also place content above the canvas</p>
</div>
</body></html>

Просмотреть файл

@ -1,163 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<!--
/*
** Copyright (c) 2012 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.
*/
-->
<script type="application/javascript" src="../util.js"></script>
<script>
"use strict";
var processor = {
lastTime : new Date,
timerCallback: function() {
if (this.video.paused || this.video.ended) {
return;
}
this.computeFrame();
var t = new Date;
var elapsed = t - this.lastTime;
this.lastTime = t;
var self = this;
setTimeout(function () {
self.timerCallback();
}, Math.max(0, 33-elapsed));
},
init: function() {
if (this.initDone) return;
this.c2 = document.getElementById("c2");
this.ctx2 = getGLContext(this.c2);
this.greenScreen = new Filter(this.ctx2, 'identity-flip-vert', 'greenScreen');
this.ctx2.activeTexture(this.ctx2.TEXTURE0);
this.tex = loadTexture(this.ctx2, this.c1, false);
this.ctx2.activeTexture(this.ctx2.TEXTURE1);
this.tex2 = loadTexture(this.ctx2, document.getElementById('i'), false);
this.ctx2.activeTexture(this.ctx2.TEXTURE0);
this.initDone = true;
},
doLoad: function() {
this.video = document.getElementById("video");
this.c1 = document.getElementById("c1");
this.ctx1 = this.c1.getContext("2d");
this.ctx1.globalCompositeOperation = 'copy';
this.ctx1.fillRect(0,0,this.c1.width, this.c1.height);
var self = this;
this.video.addEventListener("play", function() {
self.init();
self.width = self.video.videoWidth;
self.height = self.video.videoHeight;
self.lastTime = new Date;
self.timerCallback();
}, false);
},
computeFrame: function() {
// this.ctx1.drawImage(this.video, 0, 0, this.width, this.height);
this.ctx2.texImage2D(this.ctx2.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, this.video);
this.greenScreen.apply(function(s) {
s.uniform1i('Texture', 0);
s.uniform1i('Texture2', 1);
});
return;
}
};
</script>
<script id="identity-flip-vert" type="x-shader/x-vertex">
attribute vec3 Vertex;
attribute vec2 Tex;
varying vec4 texCoord0;
void main()
{
texCoord0 = vec4(Tex.s,1.0-Tex.t,0.0,0.0);
gl_Position = vec4(Vertex, 1.0);
}
</script>
<script id="greenScreen" type="x-shader/x-fragment">
precision mediump float;
uniform sampler2D Texture;
uniform sampler2D Texture2;
varying vec4 texCoord0;
void main()
{
vec4 c = texture2D(Texture, texCoord0.st);
float r = c.r * 0.5;
float a = c.g * 6.28;
float x = cos(a) * r;
float y = sin(a) * r;
vec4 c2 = texture2D(Texture2, vec2(0.7+x, 0.5+y));
// Shaders with branches are not allowed when dealing with non-SOP content
// so instead of "if (b) c2.a = 0;", we use mix()
bool b = (c.g > 120.0/255.0 && c.r > 120.0/255.0 && c.b < 50.0/255.0);
c2.a = mix(c2.a, 0.0, float(b));
gl_FragColor = c2;
}
</script>
<style>
body {
background: black;
color:#CCCCCC;
}
a {
color: white;
}
#c2 {
background-image: url(http://www.mozbox.org/pub/green/foo.png);
background-repeat: repeat;
}
div {
float: left;
border :1px solid #444444;
padding:10px;
margin: 10px;
background:#3B3B3B;
}
img { display: none; }
</style>
</head>
<body onload="processor.doLoad()">
<div>
This is a port of Paul Rouget's <a href="http://blog.mozbox.org/post/2009/02/25/video-canvas%3A-special-effects">Canvas+Video green screen demo</a>, plus a texture lookup from the Firefox logo based on the values of the green and red color channels.
</div>
<div>
<video id="video" controls="true">
<source src="http://www.mozbox.org/pub/green/video.ogv"></source>
<source src="http://cs.helsinki.fi/u/ilmarihe/c3d/demos/video.mp4"></source>
</video>
<canvas id="c1" width="320" height="192"></canvas>
</div>
<div>
<canvas id="c2" width="640" height="384"></canvas>
</div>
<img id="i" src="http://www.mozbox.org/pub/green/foo.png">
</body>
</html>

Просмотреть файл

@ -67,8 +67,14 @@ Tests.testBufferData = function(gl) {
function(){gl.bufferSubData(gl.ELEMENT_ARRAY_BUFFER, 19, new Uint16Array([1,2,3]));});
assertFail("data too large",
function(){gl.bufferSubData(gl.ELEMENT_ARRAY_BUFFER, 0, new Uint16Array(data.concat([1])));});
assertOk("offset + data too large",
assertOk("offset + data.length = end",
function(){gl.bufferSubData(gl.ELEMENT_ARRAY_BUFFER, 18, new Uint16Array([1,2,3]));});
assertOk("offset Infinity",
function(){gl.bufferSubData(gl.ELEMENT_ARRAY_BUFFER, Infinity, new Uint16Array([1,2,3]));});
assertOk("offset -Infinity",
function(){gl.bufferSubData(gl.ELEMENT_ARRAY_BUFFER, -Infinity, new Uint16Array([1,2,3]));});
assertOk("offset NaN",
function(){gl.bufferSubData(gl.ELEMENT_ARRAY_BUFFER, NaN, new Uint16Array([1,2,3]));});
assertOk("good args",
function(){gl.bufferSubData(gl.ELEMENT_ARRAY_BUFFER, 0, new Uint16Array([1,2,3]));});
throwError(gl, 'bufferData0');

Просмотреть файл

@ -89,16 +89,12 @@ Tests.testDrawArraysVBOMulti = function(gl, prog, v,n,t) {
assertOk(function(){gl.drawArrays(gl.TRIANGLES, 0, 2);});
assertOk(function(){gl.drawArrays(gl.TRIANGLES, 0, 6);});
assertOk(function(){gl.drawArrays(gl.TRIANGLES, 1, 5);});
assertFail(function(){gl.drawArrays(gl.TRIANGLES, 1, 6);});
assertFail(function(){gl.drawArrays(gl.TRIANGLES, 6, 1);});
gl.bindBuffer(gl.ARRAY_BUFFER, vbo.vbos[1]);
gl.vertexAttribPointer(n, 3, gl.FLOAT, false, 0, 0);
assertOk(function(){gl.drawArrays(gl.TRIANGLES, 5, 1);});
assertOk(function(){gl.drawArrays(gl.TRIANGLES, 0, 2);});
assertOk(function(){gl.drawArrays(gl.TRIANGLES, 0, 6);});
assertOk(function(){gl.drawArrays(gl.TRIANGLES, 1, 5);});
assertFail(function(){gl.drawArrays(gl.TRIANGLES, 1, 6);});
assertFail(function(){gl.drawArrays(gl.TRIANGLES, 6, 1);});
vbo.destroy();
assert(0 == checkError(gl, "vbo.destroy"));
}

Просмотреть файл

@ -1,305 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<!--
/*
** Copyright (c) 2012 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.
*/
-->
<link rel="stylesheet" type="text/css" href="../unit.css" />
<script type="application/javascript" src="../unit.js"></script>
<script type="application/javascript" src="../util.js"></script>
<script type="application/javascript">
var verts = [0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0];
var normals = [0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0];
var texcoords = [0.0,0.0, 1.0,0.0, 0.0,1.0];
var vertsA = new Float32Array(verts);
var normalsA = new Float32Array(normals);
var texcoordsA = new Float32Array(texcoords);
Tests.startUnit = function () {
var canvas = document.getElementById('gl');
var gl = wrapGLContext(getGLContext(canvas));
var prog = new Shader(gl, 'vert', 'frag');
prog.use();
var v = prog.attrib('Vertex');
var n = prog.attrib('Normal');
var t = prog.attrib('Tex');
return [gl,prog,v,n,t];
}
Tests.setup = function(gl, prog, v,n,t) {
return [gl, prog, v,n,t];
}
Tests.teardown = function(gl, prog, v,n,t) {
gl.disableVertexAttribArray(v);
gl.disableVertexAttribArray(n);
gl.disableVertexAttribArray(t);
}
Tests.endUnit = function(gl, prog, v,n,t) {
prog.destroy();
}
Tests.testDrawArraysEmpty = function(gl, prog, v,n,t) {
var b = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, b);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([]), gl.STATIC_DRAW);
assertOk(function(){gl.vertexAttribPointer(v, 3, gl.FLOAT, false, 0, 0);})
gl.enableVertexAttribArray(v);
assertGLError(gl, gl.INVALID_OPERATION, "zero size array",
function(){gl.drawArrays(gl.TRIANGLES, 0, 1);});
gl.deleteBuffer(b);
}
Tests.testDrawArraysOutOfBounds = function(gl, prog, v,n,t) {
var b = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, b);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([]), gl.STATIC_DRAW);
assertOk(function(){gl.vertexAttribPointer(v, 3, gl.FLOAT, false, 0, 0);});
gl.enableVertexAttribArray(v);
assertGLError(gl, gl.INVALID_OPERATION, "zero size array",
function(){gl.drawArrays(gl.TRIANGLES, 0, 1);});
assertGLError(gl, gl.INVALID_OPERATION, "zero size array 10000",
function(){gl.drawArrays(gl.TRIANGLES, 0, 10000);});
assertGLError(gl, gl.INVALID_OPERATION, "zero size array 10000000000000",
function(){gl.drawArrays(gl.TRIANGLES, 0, 10000000000000);});
assertGLError(gl, gl.INVALID_OPERATION, "zero size array fraction",
function(){gl.drawArrays(gl.TRIANGLES, 0, 1.6);});
assertGLError(gl, gl.INVALID_VALUE, "negative offset",
function(){gl.drawArrays(gl.TRIANGLES, 0, -1);});
assertGLError(gl, gl.INVALID_OPERATION, "count out of range",
function(){gl.drawArrays(gl.TRIANGLES, 0, 1);});
assertGLError(gl, gl.INVALID_VALUE, "negative count",
function(){gl.drawArrays(gl.TRIANGLES, 0, -1);});
assertGLError(gl, gl.INVALID_VALUE, "positive count, negative offset",
function(){gl.drawArrays(gl.TRIANGLES, -1, 1);});
assertGLError(gl, gl.INVALID_VALUE, "negative count, positive offset",
function(){gl.drawArrays(gl.TRIANGLES, 1, -1);});
gl.deleteBuffer(b);
}
Tests.testDrawArraysWithDataOutOfBounds = function(gl, prog, v,n,t) {
var b = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, b);
gl.bufferData(gl.ARRAY_BUFFER, vertsA, gl.STATIC_DRAW);
gl.vertexAttribPointer(v, 3, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(v);
assertGLError(gl, gl.INVALID_OPERATION, "3 element array",
function(){gl.drawArrays(gl.TRIANGLES, 3, 2);});
assertGLError(gl, gl.INVALID_OPERATION, "3 element array 10000",
function(){gl.drawArrays(gl.TRIANGLES, 0, 10000);});
assertGLError(gl, gl.INVALID_OPERATION, "3 element array 10000000000000",
function(){gl.drawArrays(gl.TRIANGLES, 0, 10000000000000);});
assertGLError(gl, gl.INVALID_OPERATION, "fractional count",
function(){gl.drawArrays(gl.TRIANGLES, 3, 1.6);});
assertGLError(gl, gl.INVALID_VALUE, "negative offset",
function(){gl.drawArrays(gl.TRIANGLES, 0, -1);});
assertGLError(gl, gl.INVALID_OPERATION, "count out of range",
function(){gl.drawArrays(gl.TRIANGLES, 0, 4);});
assertGLError(gl, gl.INVALID_VALUE, "negative count",
function(){gl.drawArrays(gl.TRIANGLES, 0, -1);});
assertGLError(gl, gl.INVALID_VALUE, "positive count, negative offset",
function(){gl.drawArrays(gl.TRIANGLES, -1, 2);});
assertGLError(gl, gl.INVALID_VALUE, "negative count, positive offset",
function(){gl.drawArrays(gl.TRIANGLES, 1, -1);});
gl.deleteBuffer(b);
}
Tests.testDrawArraysMultiOutOfBounds = function(gl, prog, v,n,t) {
var bs = [];
bs.push(gl.createBuffer());
gl.bindBuffer(gl.ARRAY_BUFFER, bs[bs.length-1]);
gl.bufferData(gl.ARRAY_BUFFER, vertsA, gl.STATIC_DRAW);
gl.vertexAttribPointer(v, 3, gl.FLOAT, false, 0, 0);
bs.push(gl.createBuffer());
gl.bindBuffer(gl.ARRAY_BUFFER, bs[bs.length-1]);
gl.bufferData(gl.ARRAY_BUFFER, normalsA, gl.STATIC_DRAW);
gl.vertexAttribPointer(n, 3, gl.FLOAT, false, 0, 0);
bs.push(gl.createBuffer());
gl.bindBuffer(gl.ARRAY_BUFFER, bs[bs.length-1]);
gl.bufferData(gl.ARRAY_BUFFER, texcoordsA, gl.STATIC_DRAW);
gl.vertexAttribPointer(t, 2, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(v);
gl.enableVertexAttribArray(n);
gl.enableVertexAttribArray(t);
assertGLError(gl, gl.INVALID_OPERATION, "multi array 1",
function(){gl.drawArrays(gl.TRIANGLES, 3, 2);});
bs.push(gl.createBuffer());
gl.bindBuffer(gl.ARRAY_BUFFER, bs[bs.length-1]);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(verts.concat(verts)), gl.STATIC_DRAW);
bs.push(gl.createBuffer());
gl.bindBuffer(gl.ARRAY_BUFFER, bs[bs.length-1]);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(texcoords.concat(texcoords)), gl.STATIC_DRAW);
gl.vertexAttribPointer(v, 3, gl.FLOAT, false, 0, 0);
gl.bindBuffer(gl.ARRAY_BUFFER, bs[1]);
gl.vertexAttribPointer(n, 3, gl.FLOAT, false, 0, 0);
gl.bindBuffer(gl.ARRAY_BUFFER, bs[2]);
gl.vertexAttribPointer(t, 2, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(v);
gl.enableVertexAttribArray(n);
gl.enableVertexAttribArray(t);
assertGLError(gl, gl.INVALID_OPERATION, "multi array 2",
function(){gl.drawArrays(gl.TRIANGLES, 3, 2);});
assertGLError(gl, gl.INVALID_OPERATION, "multi array 3",
function(){gl.drawArrays(gl.TRIANGLES, 4, 2);});
gl.bindBuffer(gl.ARRAY_BUFFER, bs[0]);
gl.vertexAttribPointer(v, 3, gl.FLOAT, false, 0, 0);
gl.bindBuffer(gl.ARRAY_BUFFER, bs[3]);
gl.vertexAttribPointer(n, 3, gl.FLOAT, false, 0, 0);
gl.bindBuffer(gl.ARRAY_BUFFER, bs[2]);
gl.vertexAttribPointer(t, 2, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(v);
gl.enableVertexAttribArray(n);
gl.enableVertexAttribArray(t);
assertGLError(gl, gl.INVALID_OPERATION, "multi array 4",
function(){gl.drawArrays(gl.TRIANGLES, 3, 2);});
assertGLError(gl, gl.INVALID_OPERATION, "multi array 5",
function(){gl.drawArrays(gl.TRIANGLES, 4, 2);});
gl.bindBuffer(gl.ARRAY_BUFFER, bs[0]);
gl.vertexAttribPointer(v, 3, gl.FLOAT, false, 0, 0);
gl.bindBuffer(gl.ARRAY_BUFFER, bs[1]);
gl.vertexAttribPointer(n, 3, gl.FLOAT, false, 0, 0);
gl.bindBuffer(gl.ARRAY_BUFFER, bs[4]);
gl.vertexAttribPointer(t, 2, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(v);
gl.enableVertexAttribArray(n);
gl.enableVertexAttribArray(t);
assertGLError(gl, gl.INVALID_OPERATION, "multi array 6",
function(){gl.drawArrays(gl.TRIANGLES, 3, 2);});
assertGLError(gl, gl.INVALID_OPERATION, "multi array 7",
function(){gl.drawArrays(gl.TRIANGLES, 3, 2);});
gl.bindBuffer(gl.ARRAY_BUFFER, bs[3]);
gl.vertexAttribPointer(v, 3, gl.FLOAT, false, 0, 0);
gl.bindBuffer(gl.ARRAY_BUFFER, bs[3]);
gl.vertexAttribPointer(n, 3, gl.FLOAT, false, 0, 0);
gl.bindBuffer(gl.ARRAY_BUFFER, bs[2]);
gl.vertexAttribPointer(t, 2, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(v);
gl.enableVertexAttribArray(n);
gl.enableVertexAttribArray(t);
assertGLError(gl, gl.INVALID_OPERATION, "multi array 8",
function(){gl.drawArrays(gl.TRIANGLES, 4, 1);});
assertGLError(gl, gl.INVALID_VALUE, "negative count",
function(){gl.drawArrays(gl.TRIANGLES, -1, 2);});
assertGLError(gl, gl.INVALID_OPERATION, "zero count???",
function(){gl.drawArrays(gl.TRIANGLES, 0, 4);});
assertGLError(gl, gl.INVALID_OPERATION, "multi array 9",
function(){gl.drawArrays(gl.TRIANGLES, 1, 4);});
bs.forEach(function(b){ gl.deleteBuffer(b) });
}
Tests.testDrawArraysVBOOutOfBounds = function(gl, prog, v,n,t) {
var vbo = new VBO(gl, {size:3, data:Quad.vertices});
vbo.use(v);
assertGLError(gl, gl.INVALID_OPERATION, "1",
function(){gl.drawArrays(gl.TRIANGLES, 6, 1);});
assertGLError(gl, gl.INVALID_VALUE, "negative count",
function(){gl.drawArrays(gl.TRIANGLES, 2, -1);});
assertGLError(gl, gl.INVALID_OPERATION, "3",
function(){gl.drawArrays(gl.TRIANGLES, 0, 7);});
assertGLError(gl, gl.INVALID_OPERATION, "4",
function(){gl.drawArrays(gl.TRIANGLES, 1, 6);});
vbo.destroy();
}
Tests.testDrawArraysVBOMultiOutOfBounds = function(gl, prog, v,n,t) {
// creates VBOs for the quad arrays, binds them with
// vertexAttribPointer and calls drawArrays
var vbo = new VBO(gl,
{size:3, data:Quad.vertices},
{size:3, data:Quad.normals},
{size:2, data:Quad.texcoords});
vbo.use(v, n, t);
assertGLError(gl, gl.INVALID_OPERATION, "1",
function(){gl.drawArrays(gl.TRIANGLES, 6, 1);});
assertGLError(gl, gl.INVALID_VALUE, "negative count",
function(){gl.drawArrays(gl.TRIANGLES, 2, -1);});
assertGLError(gl, gl.INVALID_OPERATION, "2",
function(){gl.drawArrays(gl.TRIANGLES, 0, 7);});
assertGLError(gl, gl.INVALID_OPERATION, "3",
function(){gl.drawArrays(gl.TRIANGLES, 1, 6);});
vbo.destroy();
}
Tests.testDrawArraysOOBShaderJuggle = function(gl, prog, v,n,t) {
var vbo = new VBO(gl,
{size:3, data:[0,0,0]},
{size:3, data:[0,0,0,0,0,0]});
vbo.init();
gl.bindBuffer(gl.ARRAY_BUFFER, vbo.vbos[0]);
gl.vertexAttribPointer(v, 3, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(v);
assertGLError(gl, gl.INVALID_OPERATION, "offset too big",
function(){gl.drawArrays(gl.TRIANGLES, 0, 2);});
var sh2 = new Shader(gl, 'vert', 'frag');
sh2.use();
gl.bindBuffer(gl.ARRAY_BUFFER, vbo.vbos[1]);
gl.vertexAttribPointer(sh2.attrib('Vertex'), 3, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(sh2.attrib('Vertex'));
assertOk(function(){gl.drawArrays(gl.TRIANGLES, 0, 2);});
assertGLError(gl, gl.INVALID_OPERATION, "offset too big 2",
function(){gl.drawArrays(gl.TRIANGLES, 0, 3);});
prog.use();
gl.vertexAttribPointer(prog.attrib('Vertex'), 3, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(prog.attrib('Vertex'));
assertOk(function(){gl.drawArrays(gl.TRIANGLES, 0, 2);});
assertGLError(gl, gl.INVALID_OPERATION, "offset too big 3",
function(){gl.drawArrays(gl.TRIANGLES, 0, 3);});
sh2.destroy();
}
</script>
<script id="vert" type="x-shader/x-vertex">
attribute vec3 Vertex;
attribute vec3 Normal;
attribute vec2 Tex;
varying vec4 texCoord0;
void main()
{
gl_Position = vec4(Vertex * Normal, 1.0);
texCoord0 = vec4(Tex,0.0,0.0) + gl_Position;
}
</script>
<script id="frag" type="x-shader/x-fragment">
precision mediump float;
varying vec4 texCoord0;
void main()
{
gl_FragColor = texCoord0;
}
</script>
<style>canvas{ position:absolute; }</style>
</head><body>
<canvas id="gl" width="1" height="1"></canvas>
</body></html>

Просмотреть файл

@ -94,6 +94,25 @@ Tests.testTexImage2D = function(gl) {
assertGLError(gl, gl.INVALID_OPERATION, "format and type incompatible",function(){
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, 1,1,0,gl.RGB,gl.UNSIGNED_SHORT_4_4_4_4, null);
});
assertThrows(gl, true, "too few args", function(){
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 2, 2, 0, gl.RGBA, gl.UNSIGNED_BYTE);
});
assertThrows(gl, false, "too many args", function(){
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 2, 2, 0, gl.RGBA, gl.UNSIGNED_BYTE, null, null);
});
assertThrows(gl, true, "bad TexSourceType", function(){
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, window);
});
assertThrows(gl, true, "fake TexSourceType", function(){
var fakeObj = {
get width() { throw 7 },
get height() { throw 7 },
data: new Uint8ClampedArray(10)
};
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, fakeObj);
});
}

Просмотреть файл

@ -103,6 +103,25 @@ Tests.testTexImage2D = function(gl) {
assertGLError(gl, gl.INVALID_OPERATION, "type does not match original", function(){
gl.texSubImage2D(gl.TEXTURE_2D, 0, 0,0, 1,1,gl.RGBA,gl.UNSIGNED_SHORT_4_4_4_4, new Uint16Array([0]));
});
assertThrows(gl, true, "too few args", function(){
gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE);
});
assertThrows(gl, false, "too many args", function(){
gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE, new Uint8Array([0,0,0,0]), null);
});
assertThrows(gl, true, "bad TexSourceType", function(){
gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE, window);
});
assertThrows(gl, true, "fake TexSourceType", function(){
var fakeObj = {
get width() { throw 7 },
get height() { throw 7 },
data: new Uint8ClampedArray(10)
};
gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE, fakeObj);
});
}

Просмотреть файл

@ -1,253 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<!--
/*
** Copyright (c) 2012 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.
*/
-->
<link rel="stylesheet" type="text/css" href="../unit.css" />
<script type="application/javascript" src="../unit.js"></script>
<script type="application/javascript" src="../util.js"></script>
<script type="application/javascript">
Tests.startUnit = function () {
var canvas = document.getElementById('gl');
var gl = getGLContext(canvas);
return [gl];
}
Tests.autorun = false;
Tests.message = "Caution: might hang your GPU"
var arr = ['whiletrue', 'loop100M', 'loopComp', 'variable'];
arr.forEach(function(e){
Tests['test'+e+'vert'] = function(gl) {
var sh = new Filter(gl, e+'vert', 'frag');
assertOk(function(){
sh.apply();
});
sh.destroy();
}
Tests['test'+e+'frag'] = function(gl) {
var sh = new Filter(gl, 'vert', e+'frag');
assertOk(function(){
sh.apply();
});
sh.destroy();
}
});
Tests.testMandelbrot = function(gl) {
gl.disable(gl.DEPTH_TEST);
var sh = new Filter(gl, 'identity-vert', 'mandelbrot-frag');
sh.apply(function(s){
s.uniform1f('z', 0.15);
s.uniform1f('x', -1.25);
});
for (var i=0; i<256; i++) {
sh.apply();
}
sh.destroy();
}
</script>
<script id="identity-vert" type="x-shader/x-vertex">
attribute vec3 Vertex;
attribute vec2 Tex;
varying vec2 texCoord0;
void main()
{
texCoord0 = vec2(Tex.s, Tex.t);
gl_Position = vec4(Vertex, 1.0);
}
</script>
<script id="mandelbrot-frag" type="x-shader/x-fragment">
precision mediump float;
uniform float x,y,z;
varying vec2 texCoord0;
vec4 iter_z(float cr, float ci) {
int i;
float nzr, nzi, zr = 0.0, zi = 0.0;
vec4 color = vec4(0.0);
for (i=0; i<2500; i++) {
nzr = zr * zr - zi * zi + cr;
nzi = 2.0 * zr * zi + ci;
zr = nzr;
zi = nzi;
}
color = vec4(zi);
color.a = 1.0;
return color;
}
void main()
{
gl_FragColor = iter_z(x+z*(2.0*texCoord0.s-1.5), y+z*(2.0*texCoord0.t-1.0));
}
</script>
<script id="whiletruevert" type="x-shader/x-vertex">
attribute vec3 Vertex; attribute vec2 Tex;
varying vec2 TexCoord;
void main()
{
float z = 1.0;
while(true) { z += 0.1; z *= 0.995; }
TexCoord = Tex.st;
gl_Position = vec4(Vertex, z);
}
</script>
<script id="loop100Mvert" type="x-shader/x-vertex">
attribute vec3 Vertex; attribute vec2 Tex;
varying vec2 TexCoord;
void main()
{
int i;
float z = 1.0;
for (i = 0; i<1000000000; i++) {
z += 0.1; z *= 0.995;
}
TexCoord = Tex.st;
gl_Position = vec4(Vertex, z);
}
</script>
<script id="loopCompvert" type="x-shader/x-vertex">
attribute vec3 Vertex; attribute vec2 Tex;
varying vec2 TexCoord;
void main()
{
float z = 1.0;
while(z > 0.0) { z += 0.1; z *= 0.995; }
TexCoord = Tex.st;
gl_Position = vec4(Vertex, z);
}
</script>
<script id="variablevert" type="x-shader/x-vertex">
attribute vec3 Vertex; attribute vec2 Tex;
varying vec2 TexCoord;
void main()
{
float z = 1.0;
while(z > Vertex.z) { z += 0.1; z *= 0.995; }
TexCoord = Tex.st;
gl_Position = vec4(Vertex, z);
}
</script>
<script id="vert" type="x-shader/x-vertex">
attribute vec3 Vertex; attribute vec2 Tex;
varying vec2 TexCoord;
void main()
{
TexCoord = Tex.st;
gl_Position = vec4(Vertex, 0.0);
}
</script>
<script id="whiletruefrag" type="x-shader/x-fragment">
precision mediump float;
varying vec2 TexCoord;
void main()
{
float z = 1.0;
while(true) { z += 0.1; z *= 0.995; }
gl_FragColor = vec4(1.0, TexCoord.s, TexCoord.t, z);
}
</script>
<script id="loop100Mfrag" type="x-shader/x-fragment">
precision mediump float;
varying vec2 TexCoord;
void main()
{
int i;
float z = 1.0;
for (i = 0; i<1000000000; i++) {
z += 0.1; z *= 0.995;
}
gl_FragColor = vec4(1.0, TexCoord.s, TexCoord.t, z);
}
</script>
<script id="loopCompfrag" type="x-shader/x-fragment">
precision mediump float;
varying vec2 TexCoord;
void main()
{
float z = TexCoord.s;
while(z > 0.0) { z += 0.1; z *= 0.995; }
gl_FragColor = vec4(1.0, TexCoord.s, TexCoord.t, z);
}
</script>
<script id="variablefrag" type="x-shader/x-fragment">
precision mediump float;
varying vec2 TexCoord;
void main()
{
float z = 1.0;
while(z > TexCoord.s) { z += 0.1; z *= 0.995; }
gl_FragColor = vec4(1.0, TexCoord.s, TexCoord.t, z);
}
</script>
<script id="frag" type="x-shader/x-fragment">
precision mediump float;
varying vec2 TexCoord;
void main()
{
gl_FragColor = vec4(1.0, TexCoord.s, TexCoord.t, 1.0);
}
</script>
<style>canvas{ position:absolute; }</style>
</head><body>
<canvas id="gl" width="512" height="512"></canvas>
</body></html>

Просмотреть файл

@ -1,115 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<!--
/*
** Copyright (c) 2012 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.
*/
-->
<link rel="stylesheet" type="text/css" href="../unit.css" />
<script type="application/javascript" src="../unit.js"></script>
<script type="application/javascript" src="../util.js"></script>
<script type="application/javascript">
Tests.autorun = false;
Tests.message = "Caution: may crash the browser";
Tests.startUnit = function () {
var canvas = document.getElementById('gl');
var gl = getGLContext(canvas);
return [gl];
}
Tests.testPassingTooManyVBOs = function(gl) {
var sh = new Filter(gl, 'vert', 'frag');
assertFail(function(){sh.apply();});
sh.destroy();
}
Tests.testPassingTooManyUniforms = function(gl) {
var sh = new Filter(gl, 'vert2', 'frag2');
sh.apply(function(f){
assertFail(function(){f.uniform1f('foo', 3.0);throwError("foo")});
f.uniform1f('bar', 1.0);
assertFail(function(){f.uniform1f('baz', 1.0);throwError("baz")});
});
sh.destroy();
}
</script>
<script id="vert" type="x-shader/x-vertex">
attribute vec3 Vertex; attribute vec2 Tex;
varying vec2 TexCoord;
void main()
{
TexCoord = Vertex.st;
gl_Position = vec4(Vertex, 0.0);
}
</script>
<script id="frag" type="x-shader/x-fragment">
precision mediump float;
void main()
{
gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
}
</script>
<script id="vert2" type="x-shader/x-vertex">
uniform float foo, bar;
attribute vec3 Vertex; attribute vec2 Tex;
varying vec2 TexCoord;
void main()
{
TexCoord = Tex.st;
gl_Position = vec4(Vertex, bar);
}
</script>
<script id="frag2" type="x-shader/x-fragment">
precision mediump float;
uniform float baz;
varying vec2 TexCoord;
void main()
{
gl_FragColor = vec4(1.0, TexCoord.s, 0.0, 1.0);
}
</script>
<style>canvas{ position:absolute; }</style>
</head><body>
<canvas id="gl" width="1" height="1"></canvas>
</body></html>

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

Просмотреть файл

@ -1,85 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<!--
/*
** Copyright (c) 2012 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.
*/
-->
<link rel="stylesheet" type="text/css" href="../unit.css" />
<script type="application/javascript" src="../unit.js"></script>
<script type="application/javascript" src="../util.js"></script>
<script type="application/javascript">
Tests.autorun = false;
Tests.testInterval = function() {
document.getElementById('dtMax').textContent = "Running, please wait...";
setTimeout(function() {
var t0 = new Date().getTime();
var t = t0;
var dtMax = 0;
var frames = [];
var iv;
iv = setInterval(function() {
if (t > t0 + 10000) {
var hist = [];
var dtMed = 0, maxi = [0, 0];
for (var i=0; i<dtMax; i++) hist[i] = 0;
for (var i=0; i<frames.length; i++)
hist[frames[i]]++;
for (var i=0; i<hist.length; i++)
if (hist[i] > maxi[1]) maxi = [i, hist[i]];
dtMed = maxi[0];
var dtAvg = frames.reduce(function(s,i){return s + i;})/frames.length;
document.getElementById('dtMax').textContent = "Longest frame: " + dtMax + " ms. Average frame: " + Math.floor(dtAvg*100)*0.01 + " ms. Median frame: " + dtMed + " ms.";
clearInterval(iv);
var c = document.getElementById('dtCanvas');
c.width = frames.length;
c.height = dtMax;
var ctx = c.getContext('2d');
for (var i=0; i<frames.length; i++)
ctx.fillRect(i,0,1,frames[i]);
}
var t1 = new Date().getTime();
if (t1-t > dtMax) dtMax = t1-t;
frames.push(t1-t);
t = t1;
var rot = Matrix.rotate((t/400) % (2*Math.PI), [0, 1+(t%1000), 1]);
var trans = Matrix.translate3(0, Math.cos(t/1000)*1, Math.sin(t/1000)*3);
for (var i=0; i<200; i++)
var mat = Matrix.mul4x4(rot, trans);
}, 16);
}, 0);
}
</script>
<style>canvas{ position:absolute; }</style>
</head><body>
<h3>10 seconds of 60fps 200x mul4x4, frame time statistics</h3>
<p id="dtMax"></p>
<canvas id="dtCanvas"></canvas>
</body></html>

Просмотреть файл

@ -1,77 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<!--
/*
** Copyright (c) 2012 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.
*/
-->
<link rel="stylesheet" type="text/css" href="../unit.css" />
<script type="application/javascript" src="../unit.js"></script>
<script type="application/javascript" src="../util.js"></script>
<script type="application/javascript">
Tests.autorun = false;
Tests.message = "This might take a second or two (or ten)";
Tests.testMatrixMultiply = function() {
time("testMatrixMultiply", function() {
var mat = Matrix.identity;
for (var i=0; i<1000000; i++)
Matrix.mul4x4(mat, mat);
});
}
Tests.testTransformStack = function() {
time("testTransformStack", function() {
var j = 0;
for (var i=0; i<1000; i++) {
var t = new Date().getTime();
var pmat = Matrix.perspective(30, 600/400, 1, 100+(t%1000));
var look = Matrix.lookAt([4,-1,8], [-0.2,0+(t%1000),0], [0,1,0]);
var rot = Matrix.rotate((t/400) % (2*Math.PI), [0, 1+(t%1000), 1]);
var trans = Matrix.translate3(0, Math.cos(t/1000)*1, Math.sin(t/1000)*3);
var sca = Matrix.scale1(0.6+(t%1000));
var vmat = Matrix.identity;
vmat = Matrix.mul4x4(vmat, pmat);
vmat = Matrix.mul4x4(vmat, look);
vmat = Matrix.mul4x4(vmat, trans);
vmat = Matrix.mul4x4(vmat, sca);
vmat = Matrix.mul4x4(vmat, rot);
j += vmat.length;
}
Tests.j = j;
});
}
</script>
<style>canvas{ position:absolute; }</style>
</head><body>
<h3>1000000x JavaScript Matrix.mul4x4</h3>
<p id="testMatrixMultiply"></p>
<h3>1000x JavaScript transform stack</h3>
<p id="testTransformStack"></p>
</body></html>

Просмотреть файл

@ -1,67 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<!--
/*
** Copyright (c) 2012 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.
*/
-->
<link rel="stylesheet" type="text/css" href="../unit.css" />
<script type="application/javascript" src="../unit.js"></script>
<script type="application/javascript" src="../util.js"></script>
<script type="application/javascript">
Tests.autorun = false;
Tests.message = "This might take a second or two";
Tests.testGLOverhead = function() {
var gl = document.getElementById("gl").getContext(GL_CONTEXT_ID);
var fakeGl = {getError: function(){ return 0; }};
time("testGLOverhead", function() {
for (var i=0; i<1000000; i++)
gl.getError();
});
time("testJSOverhead", function() {
for (var i=0; i<1000000; i++)
fakeGl.getError();
});
time("testLoopOverhead", function() {
for (var i=0; i<1000000;)
i++;
});
}
</script>
<style>canvas{ position:absolute; }</style>
</head><body>
<canvas id="gl" width="16" height="16"></canvas>
<h3>1000000x gl.getError() (measuring JS->GL call overhead)</h3>
<p id="testGLOverhead"></p>
<h3>1000000x fakeGl.getError() (measuring JS->JS call overhead)</h3>
<p id="testJSOverhead"></p>
<h3>1000000x i++ (measuring loop overhead)</h3>
<p id="testLoopOverhead"></p>
</body></html>

Просмотреть файл

@ -1097,6 +1097,24 @@ function assertThrowNoGLError(gl, name, f) {
return true;
}
function assertThrows(gl, shouldThrow, info, func) {
var didThrow = false;
try {
func();
} catch (e) {
var didGLError = (e instanceof GLError);
if (!didGLError) {
didThrow = true;
}
}
var text = shouldThrow ? "Should throw: "
: "Should not throw: ";
var func = (didThrow == shouldThrow) ? testPassed : testFailed;
func(text + info);
}
Quad = {
vertices : [
-1,-1,0,

Просмотреть файл

@ -40,37 +40,71 @@
<script>
"use strict";
description("This test checks whether OffscreenCanvas webgl context honors the preserveDrawingBuffer flag.");
const wtu = WebGLTestUtils;
const pixels = new Uint8Array(4);
function getPixelsFromOffscreenWebgl(preserveFlag) {
var canvas = document.createElement("canvas");
var offscreenCanvas = transferredOffscreenCanvasCreation(canvas, 10, 10);
var gl = offscreenCanvas.getContext("webgl", {preserveDrawingBuffer: preserveFlag});
function checkPixels(color) {
return (color[0] === pixels[0]) &&
(color[1] === pixels[1]) &&
(color[2] === pixels[2]) &&
(color[3] === pixels[3]);
}
// Draw some color on gl and commit
const nextFrame = () => new Promise(r => requestAnimationFrame(r));
async function getPixelsFromOffscreenWebgl(preserveFlag, color, msg) {
const canvas = document.createElement("canvas");
const offscreenCanvas = transferredOffscreenCanvasCreation(canvas, 10, 10);
const gl = offscreenCanvas.getContext("webgl", {preserveDrawingBuffer: preserveFlag});
// Draw some color on gl
gl.clearColor(1, 0, 1, 1);
gl.clear(gl.COLOR_BUFFER_BIT);
gl.commit();
var pixels = new Uint8Array(4);
gl.readPixels(0, 0, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, pixels);
return pixels;
let t;
const t0 = await nextFrame();
for (;;) {
t = await nextFrame();
gl.readPixels(0, 0, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, pixels);
if (preserveFlag) {
if (!checkPixels(color)) {
testFailed(msg + '\nexpected: ' + color.toString() + ' was ' + pixels.toString());
return;
}
} else {
if (checkPixels(color)) {
testPassed(msg);
return;
}
}
// Keep checking until it takes up to a certain time
if (t > t0 + 500) {
break;
}
}
if (preserveFlag) {
testPassed(msg);
} else {
testFailed(msg + '\nexpected: ' + color.toString() + ' was ' + pixels.toString());
}
}
if (!window.OffscreenCanvas) {
testPassed("No OffscreenCanvas support");
} else {
// Test if OffscreenCanvas.webgl retains context if preserveDrawingBuffer is true.
var pixelsPreserve = getPixelsFromOffscreenWebgl(true);
shouldBe(pixelsPreserve, [255,0,255,255]);
(async () => {
if (!window.OffscreenCanvas) {
testPassed("No OffscreenCanvas support");
} else {
// Test if OffscreenCanvas.webgl retains contents if preserveDrawingBuffer is true.
await getPixelsFromOffscreenWebgl(true, [255,0,255,255], "should be preserved");
// Test if OffscreenCanvas.webgl loses context if presereDrawingbuffer is false.
var pixelsNoPreserve = getPixelsFromOffscreenWebgl(false);
shouldBe(pixelsNoPreserve, [0,0,0,0]);
}
var successfullyParsed = true;
// Test if OffscreenCanvas.webgl loses contents if preserveDrawingBuffer is false.
await getPixelsFromOffscreenWebgl(false, [0, 0, 0, 0], "should not be preserved");
finishTest();
}
})();
</script>
<script src="../../js/js-test-post.js"></script>
</body>
</html>

Просмотреть файл

@ -28,7 +28,7 @@
<html>
<head>
<meta charset="utf-8">
<title>Resizing Test for OffscreenCanvas</title>
<title>Resizing Test for OffscreenCanvas commit()</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>
@ -39,7 +39,7 @@
<div id="console"></div>
<script>
"use strict";
description("This test ensures that the OffscreenCanvas context returns the correct image size after resizing.");
description("This test ensures that the OffscreenCanvas context returns the correct image size after resizing and calling commit().");
function testResizeOnNewOffscreenCanvas() {
var canvas = new OffscreenCanvas(10, 20);
@ -102,6 +102,9 @@ function testResizeOnTransferredOffscreenCanvas() {
if (!window.OffscreenCanvas) {
testPassed("No OffscreenCanvas support");
finishTest();
} else if (!new OffscreenCanvas(10, 20).getContext("webgl").commit) {
testPassed("commit() not supported");
finishTest();
} else {
testResizeOnNewOffscreenCanvas();
testResizeOnTransferredOffscreenCanvas();

Просмотреть файл

@ -103,6 +103,7 @@ if (!gl) {
var result_2 = new Uint8Array(N * N * 4);
gl.readPixels(0, 0, N, N, gl.RGBA, gl.UNSIGNED_BYTE, result_1);
gl.readPixels(0, 0, N, N, gl.RGBA, gl.UNSIGNED_BYTE, result_2);
wtu.glErrorShouldBe(gl, gl.NO_ERROR);
var tolerance = 0;
var diff = new Uint8Array(N * N * 4);

Просмотреть файл

@ -56,6 +56,7 @@ void main()
</head>
<body>
<canvas id="example" width="32" height="32"></canvas>
<canvas id="example2" width="32" height="32"></canvas>
<div id="description"></div>
<div id="console"></div>
<script>
@ -220,43 +221,51 @@ function runTestIteration(format, type, packAlignment, width, height)
description('Verify readPixels() works fine with various PACK_ALIGNMENT values.');
shouldBeNonNull("gl = wtu.create3DContext('example')")
shouldBeNonNull("program = wtu.setupProgram(gl, ['vshader', 'fshader'], ['pos', 'colorIn'])");
debug("<h1>antialias = false</h1>");
shouldBeNonNull("gl = wtu.create3DContext('example', {antialias: false})")
var formats = [ gl.RGBA ];
var formatNames = [ "RGBA" ];
runAllIterations();
debug("<h1>antialias = true</h1>");
shouldBeNonNull("gl = wtu.create3DContext('example2', {antialias: true})")
runAllIterations();
for (var i = 0; i < formats.length; ++i) {
var format = formats[i];
function runAllIterations() {
shouldBeNonNull("program = wtu.setupProgram(gl, ['vshader', 'fshader'], ['pos', 'colorIn'])");
debug("Testing format = " + formatNames[i] + " and type = UNSIGNED_BYTE");
runTestIteration(format, gl.UNSIGNED_BYTE, 1, 1, 2);
runTestIteration(format, gl.UNSIGNED_BYTE, 2, 1, 2);
runTestIteration(format, gl.UNSIGNED_BYTE, 4, 1, 2);
runTestIteration(format, gl.UNSIGNED_BYTE, 8, 1, 2);
runTestIteration(format, gl.UNSIGNED_BYTE, 4, 2, 2);
runTestIteration(format, gl.UNSIGNED_BYTE, 8, 2, 2);
runTestIteration(format, gl.UNSIGNED_BYTE, 4, 3, 2);
runTestIteration(format, gl.UNSIGNED_BYTE, 8, 3, 2);
runTestIteration(format, gl.UNSIGNED_BYTE, 4, 4, 2);
runTestIteration(format, gl.UNSIGNED_BYTE, 8, 4, 2);
runTestIteration(format, gl.UNSIGNED_BYTE, 8, 5, 1);
runTestIteration(format, gl.UNSIGNED_BYTE, 4, 5, 2);
runTestIteration(format, gl.UNSIGNED_BYTE, 8, 5, 2);
runTestIteration(format, gl.UNSIGNED_BYTE, 8, 6, 2);
runTestIteration(format, gl.UNSIGNED_BYTE, 8, 7, 2);
runTestIteration(format, gl.UNSIGNED_BYTE, 8, 8, 2);
runTestIteration(format, gl.UNSIGNED_BYTE, 1, 0, 0);
runTestIteration(format, gl.UNSIGNED_BYTE, 2, 0, 0);
runTestIteration(format, gl.UNSIGNED_BYTE, 4, 0, 0);
runTestIteration(format, gl.UNSIGNED_BYTE, 8, 0, 0);
runTestIteration(format, gl.UNSIGNED_BYTE, 1, -1, 1);
runTestIteration(format, gl.UNSIGNED_BYTE, 2, 1, -1);
runTestIteration(format, gl.UNSIGNED_BYTE, 4, 0, -1);
runTestIteration(format, gl.UNSIGNED_BYTE, 8, -1, -1);
for (var i = 0; i < formats.length; ++i) {
var format = formats[i];
debug("Testing format = " + formatNames[i] + " and type = UNSIGNED_BYTE");
runTestIteration(format, gl.UNSIGNED_BYTE, 1, 1, 2);
runTestIteration(format, gl.UNSIGNED_BYTE, 2, 1, 2);
runTestIteration(format, gl.UNSIGNED_BYTE, 4, 1, 2);
runTestIteration(format, gl.UNSIGNED_BYTE, 8, 1, 2);
runTestIteration(format, gl.UNSIGNED_BYTE, 4, 2, 2);
runTestIteration(format, gl.UNSIGNED_BYTE, 8, 2, 2);
runTestIteration(format, gl.UNSIGNED_BYTE, 4, 3, 2);
runTestIteration(format, gl.UNSIGNED_BYTE, 8, 3, 2);
runTestIteration(format, gl.UNSIGNED_BYTE, 4, 4, 2);
runTestIteration(format, gl.UNSIGNED_BYTE, 8, 4, 2);
runTestIteration(format, gl.UNSIGNED_BYTE, 8, 5, 1);
runTestIteration(format, gl.UNSIGNED_BYTE, 4, 5, 2);
runTestIteration(format, gl.UNSIGNED_BYTE, 8, 5, 2);
runTestIteration(format, gl.UNSIGNED_BYTE, 8, 6, 2);
runTestIteration(format, gl.UNSIGNED_BYTE, 8, 7, 2);
runTestIteration(format, gl.UNSIGNED_BYTE, 8, 8, 2);
runTestIteration(format, gl.UNSIGNED_BYTE, 1, 0, 0);
runTestIteration(format, gl.UNSIGNED_BYTE, 2, 0, 0);
runTestIteration(format, gl.UNSIGNED_BYTE, 4, 0, 0);
runTestIteration(format, gl.UNSIGNED_BYTE, 8, 0, 0);
runTestIteration(format, gl.UNSIGNED_BYTE, 1, -1, 1);
runTestIteration(format, gl.UNSIGNED_BYTE, 2, 1, -1);
runTestIteration(format, gl.UNSIGNED_BYTE, 4, 0, -1);
runTestIteration(format, gl.UNSIGNED_BYTE, 8, -1, -1);
}
}
var successfullyParsed = true;
</script>
<script src="../../js/js-test-post.js"></script>
</body>

Просмотреть файл

@ -37,6 +37,7 @@
</head>
<body>
<canvas id="example" width="200" height="200" style="width: 20px; height: 20px"></canvas>
<canvas id="example2" width="200" height="200" style="width: 20px; height: 20px"></canvas>
<div id="description"></div>
<div id="console"></div>
<script>
@ -44,273 +45,290 @@
description("Checks that ReadPixels works as expected.");
var wtu = WebGLTestUtils;
var canvas = document.getElementById("example");
var gl = wtu.create3DContext(canvas);
var contextVersion = wtu.getDefault3DContextVersion();
debug("<h1>antialias = false</h1>")
runTest(document.getElementById("example"), false);
debug("<h1>antialias = true</h1>")
runTest(document.getElementById("example2"), true);
finishTest();
var actual;
var expected;
var width = 2;
var height = 2;
var continueTestFunc = continueTestPart1;
gl.clearColor(1, 1, 1, 1);
gl.clear(gl.COLOR_BUFFER_BIT);
function runTest(canvas, antialias) {
var gl = wtu.create3DContext(canvas, {antialias: antialias});
var contextVersion = wtu.getDefault3DContextVersion();
// Resize the canvas to 2x2. This is an attempt to get stuff in the backbuffer.
// that shouldn't be there.
canvas.addEventListener("webglcontextlost", function(e) { e.preventDefault(); }, false);
canvas.addEventListener("webglcontextrestored", continueTestAfterContextRestored, false);
canvas.width = width;
canvas.height = height;
if (gl.getError() != gl.CONTEXT_LOST_WEBGL) {
continueTestPart1();
}
var width = 2;
var height = 2;
var continueTestFunc = continueTestPart1;
function continueTestAfterContextRestored() {
window.gl = wtu.create3DContext(canvas);
var func = continueTestFunc;
window.continueTestFunc = function() { testFailed("should not be here"); };
func();
}
function continueTestPart1() {
gl.clearColor(0.2, 0.6, 0.4, 1);
gl.clearColor(1, 1, 1, 1);
gl.clear(gl.COLOR_BUFFER_BIT);
var innerColor = [51, 153, 102, 255]; // (0.2, 0.6, 0.4, 1)
var outerColor = [19, 72, 0, 198]; // Random color other than [0, 0, 0, 0]
var tests = [
{ msg: 'in range', checkColor: innerColor, x: 0, y: 0,
oneColor: innerColor, oneX: 0, oneY: 0},
{ msg: 'off top left', checkColor: outerColor, x: -1, y: -1,
oneColor: innerColor, oneX: 1, oneY: 1},
{ msg: 'off bottom right', checkColor: outerColor, x: 1, y: 1,
oneColor: innerColor, oneX: 0, oneY: 0},
{ msg: 'completely off top ', checkColor: outerColor, x: 0, y: -2,
oneColor: outerColor, oneX: 0, oneY: 0},
{ msg: 'completely off bottom', checkColor: outerColor, x: 0, y: 2,
oneColor: outerColor, oneX: 0, oneY: 0},
{ msg: 'completely off left', checkColor: outerColor, x: -2, y: 0,
oneColor: outerColor, oneX: 0, oneY: 0},
{ msg: 'completeley off right', checkColor: outerColor, x: 2, y: 0,
oneColor: outerColor, oneX: 0, oneY: 0}
];
for (var tt = 0; tt < tests.length; ++tt) {
var test = tests[tt];
debug("");
debug("checking: " + test.msg);
checkBuffer(test.checkColor, test.x, test.y,
test.oneColor, test.oneX, test.oneY);
}
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "there should be no GL errors");
function checkBuffer(checkColor, x, y, oneColor, oneX, oneY) {
var buf = new Uint8Array(width * height * 4);
// Initialize buf.
for (var ii = 0; ii < width * height; ++ii) {
buf[ii * 4] = outerColor[0];
buf[ii * 4 + 1] = outerColor[1];
buf[ii * 4 + 2] = outerColor[2];
buf[ii * 4 + 3] = outerColor[3];
}
gl.readPixels(x, y, width, height, gl.RGBA, gl.UNSIGNED_BYTE, buf);
for (var yy = 0; yy < height; ++yy) {
for (var xx = 0; xx < width; ++xx) {
var offset = (yy * width + xx) * 4;
var expectedColors = (oneX == xx && oneY == yy) ? oneColor : checkColor;
var mismatch = false;
for (var cc = 0; cc < 4; ++cc) {
var expectedColor = expectedColors[cc];
var color = buf[offset + cc];
var diff = Math.abs(expectedColor - color);
if (diff >= 3) {
mismatch = true;
break;
}
}
assertMsg(!mismatch,
"color pixel at " + xx + ", " + yy + " should be about " + expectedColors +
", was = " + [buf[offset], buf[offset + 1], buf[offset + 2], buf[offset + 3]]);
}
}
}
continueTestPart2();
}
function continueTestPart2() {
var invalidFormat = [gl.DEPTH_COMPONENT, gl.DEPTH_STENCIL, desktopGL.R8, gl.RGBA4, gl.LUMINANCE, gl.LUMINANCE_ALPHA];
if (contextVersion < 2) {
// They are valid in WebGL 2 or higher
invalidFormat = invalidFormat.concat([desktopGL.RED, desktopGL.RG_INTEGER, desktopGL.RGBA_INTEGER]);
}
var invalidTypeInfo = [
{type: desktopGL.UNSIGNED_INT_24_8, dest: new Uint32Array(4)}
];
if (contextVersion < 2) {
// They are valid in WebGL 2 or Higher
invalidTypeInfo = invalidTypeInfo.concat([
{type: gl.UNSIGNED_SHORT, dest: new Uint16Array(4)},
{type: gl.SHORT, dest: new Int16Array(4)},
{type: gl.BYTE, dest: new Int8Array(4)},
{type: gl.UNSIGNED_INT, dest: new Uint32Array(4)},
{type: desktopGL.UNSIGNED_INT_2_10_10_10_REV, dest: new Uint32Array(4)}
]);
}
debug("");
debug("check invalid format or type");
for (var ff = 0; ff < invalidFormat.length; ++ff) {
var format = invalidFormat[ff];
var buf = new Uint8Array(4);
gl.readPixels(0, 0, 1, 1, format, gl.UNSIGNED_BYTE, buf);
wtu.glErrorShouldBe(gl, [gl.INVALID_ENUM, gl.INVALID_OPERATION], "Should not be able to read as " + wtu.glEnumToString(gl, format));
}
for (var tt = 0; tt < invalidTypeInfo.length; ++tt) {
var info = invalidTypeInfo[tt];
var type = info.type;
var dest = info.dest;
gl.readPixels(0, 0, 1, 1, gl.RGBA, type, dest);
wtu.glErrorShouldBe(gl, [gl.INVALID_ENUM, gl.INVALID_OPERATION], "Should not be able to read as " + wtu.glEnumToString(gl, type));
}
var combinations = [
{
format: gl.RGBA,
type: gl.UNSIGNED_BYTE,
dest: new Uint8Array(4),
},
{
format: gl.RGB,
type: gl.UNSIGNED_BYTE,
dest: new Uint8Array(3),
},
{
format: gl.RGB,
type: gl.UNSIGNED_SHORT_5_6_5,
dest: new Uint8Array(3),
},
{
format: gl.RGBA,
type: gl.UNSIGNED_SHORT_5_5_5_1,
dest: new Uint16Array(1),
},
{
format: gl.RGBA,
type: gl.UNSIGNED_SHORT_4_4_4_4,
dest: new Uint16Array(1),
},
{
format: gl.ALPHA,
type: gl.UNSIGNED_BYTE,
dest: new Uint8Array(1),
}
];
if (contextVersion > 1) {
combinations = combinations.concat([
{
format: gl.RED,
type: gl.UNSIGNED_BYTE,
dest: new Uint8Array(1),
},
{
format: gl.RGBA_INTEGER,
type: gl.UNSIGNED_INT,
dest: new Uint32Array(4),
},
{
format: gl.RGBA_INTEGER,
type: gl.INT,
dest: new Int32Array(4),
}
]);
}
debug("");
debug("check invalid combinations of format/type");
var implFormat = gl.getParameter(gl.IMPLEMENTATION_COLOR_READ_FORMAT);
var implType = gl.getParameter(gl.IMPLEMENTATION_COLOR_READ_TYPE);
for (var tt = 0; tt < combinations.length; ++ tt) {
var info = combinations[tt];
var format = info.format;
var type = info.type;
var dest = info.dest;
gl.readPixels(0, 0, 1, 1, format, type, dest);
// Only two format/type parameter pairs are accepted. GL_RGBA/GL_UNSIGNED_BYTE is always
// accepted on default readbuffer. The other acceptable pair can be discovered by querying
// GL_IMPLEMENTATION_COLOR_READ_FORMAT and GL_IMPLEMENTATION_COLOR_READ_TYPE.
if ((format == gl.RGBA && type == gl.UNSIGNED_BYTE) || (format == implFormat && type == implType)) {
wtu.glErrorShouldBe(
gl, gl.NO_ERROR,
"Should be able to read as " + wtu.glEnumToString(gl, format) +
" / " + wtu.glEnumToString(gl, type));
} else {
wtu.glErrorShouldBe(
gl, gl.INVALID_OPERATION,
"Should not be able to read as " + wtu.glEnumToString(gl, format) +
" / " + wtu.glEnumToString(gl, type));
}
}
debug("");
debug("check reading with lots of drawing");
continueTestFunc = continueTestPart3;
width = 1024;
height = 1024;
// Resize the canvas to 2x2. This is an attempt to get stuff in the backbuffer.
// that shouldn't be there.
canvas.addEventListener("webglcontextlost", function(e) { e.preventDefault(); }, false);
canvas.addEventListener("webglcontextrestored", continueTestAfterContextRestored, false);
canvas.width = width;
canvas.height = height;
if (gl.getError() != gl.CONTEXT_LOST_WEBGL) {
continueTestPart3();
continueTestPart1();
}
}
function continueTestPart3() {
gl.viewport(0, 0, 1024, 1024);
var program = wtu.setupTexturedQuad(gl);
var loc = gl.getUniformLocation(program, "tex");
gl.disable(gl.BLEND);
gl.disable(gl.DEPTH_TEST);
var colors = [[255, 0, 0, 255], [0, 255, 0, 255], [0, 0, 255, 255]];
var textures = [];
var results = [];
for (var ii = 0; ii < colors.length; ++ii) {
gl.activeTexture(gl.TEXTURE0 + ii);
var tex = gl.createTexture();
wtu.fillTexture(gl, tex, 1, 1, colors[ii]);
textures.push(tex);
function continueTestAfterContextRestored() {
window.gl = wtu.create3DContext(canvas);
var func = continueTestFunc;
window.continueTestFunc = function() { testFailed("should not be here"); };
func();
}
for (var ii = 0; ii < colors.length; ++ii) {
for (var jj = 0; jj < 300 + ii + 1; ++jj) {
gl.uniform1i(loc, jj % 3);
gl.drawArrays(gl.TRIANGLES, 0, 6);
function continueTestPart1() {
gl.clearColor(0.2, 0.6, 0.4, 1);
gl.clear(gl.COLOR_BUFFER_BIT);
var innerColor = [51, 153, 102, 255]; // (0.2, 0.6, 0.4, 1)
var outerColor = [19, 72, 0, 198]; // Random color other than [0, 0, 0, 0]
var tests = [
{ msg: 'in range', checkColor: innerColor, x: 0, y: 0,
oneColor: innerColor, oneX: 0, oneY: 0},
{ msg: 'off top left', checkColor: outerColor, x: -1, y: -1,
oneColor: innerColor, oneX: 1, oneY: 1},
{ msg: 'off bottom right', checkColor: outerColor, x: 1, y: 1,
oneColor: innerColor, oneX: 0, oneY: 0},
{ msg: 'completely off top ', checkColor: outerColor, x: 0, y: -2,
oneColor: outerColor, oneX: 0, oneY: 0},
{ msg: 'completely off bottom', checkColor: outerColor, x: 0, y: 2,
oneColor: outerColor, oneX: 0, oneY: 0},
{ msg: 'completely off left', checkColor: outerColor, x: -2, y: 0,
oneColor: outerColor, oneX: 0, oneY: 0},
{ msg: 'completeley off right', checkColor: outerColor, x: 2, y: 0,
oneColor: outerColor, oneX: 0, oneY: 0}
];
for (var tt = 0; tt < tests.length; ++tt) {
var test = tests[tt];
debug("");
debug("checking: " + test.msg);
checkBuffer(test.checkColor, test.x, test.y,
test.oneColor, test.oneX, test.oneY);
}
var buf = new Uint8Array(4);
gl.readPixels(512, 512, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, buf);
results.push(buf);
for (var kk = 0; kk < 99; ++kk) {
gl.uniform1i(loc, (jj + kk) % 3);
gl.drawArrays(gl.TRIANGLES, 0, 6);
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "there should be no GL errors");
function checkBuffer(checkColor, x, y, oneColor, oneX, oneY) {
var buf = new Uint8Array(width * height * 4);
// Initialize buf.
for (var ii = 0; ii < width * height; ++ii) {
buf[ii * 4] = outerColor[0];
buf[ii * 4 + 1] = outerColor[1];
buf[ii * 4 + 2] = outerColor[2];
buf[ii * 4 + 3] = outerColor[3];
}
gl.readPixels(x, y, width, height, gl.RGBA, gl.UNSIGNED_BYTE, buf);
for (var yy = 0; yy < height; ++yy) {
for (var xx = 0; xx < width; ++xx) {
var offset = (yy * width + xx) * 4;
var expectedColors = (oneX == xx && oneY == yy) ? oneColor : checkColor;
var mismatch = false;
for (var cc = 0; cc < 4; ++cc) {
var expectedColor = expectedColors[cc];
var color = buf[offset + cc];
var diff = Math.abs(expectedColor - color);
if (diff >= 3) {
mismatch = true;
break;
}
}
assertMsg(!mismatch,
"color pixel at " + xx + ", " + yy + " should be about " + expectedColors +
", was = " + [buf[offset], buf[offset + 1], buf[offset + 2], buf[offset + 3]]);
}
}
}
continueTestPart2();
}
function continueTestPart2() {
let neverValidFormats = [gl.DEPTH_COMPONENT, gl.DEPTH_STENCIL, desktopGL.R8, gl.RGBA4];
let maybeValidFormats = [gl.LUMINANCE, gl.LUMINANCE_ALPHA];
if (contextVersion < 2) {
// They are valid in WebGL 2 or higher
maybeValidFormats = maybeValidFormats.concat([desktopGL.RED, desktopGL.RG_INTEGER, desktopGL.RGBA_INTEGER]);
}
let neverValidTypeInfo = [
{type: desktopGL.UNSIGNED_INT_24_8, dest: new Uint32Array(4)}
];
let maybeValidTypeInfo = [];
if (contextVersion < 2) {
// They are valid in WebGL 2 or Higher
maybeValidTypeInfo = maybeValidTypeInfo.concat([
{type: gl.UNSIGNED_SHORT, dest: new Uint16Array(4)},
{type: gl.SHORT, dest: new Int16Array(4)},
{type: gl.BYTE, dest: new Int8Array(4)},
{type: gl.UNSIGNED_INT, dest: new Uint32Array(4)},
{type: desktopGL.UNSIGNED_INT_2_10_10_10_REV, dest: new Uint32Array(4)}
]);
}
debug("");
debug("check non-default format or type");
for (let format of neverValidFormats) {
var buf = new Uint8Array(4);
gl.readPixels(0, 0, 1, 1, format, gl.UNSIGNED_BYTE, buf);
wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, "Should not be able to read as " + wtu.glEnumToString(gl, format));
}
for (let format of maybeValidFormats) {
var buf = new Uint8Array(4);
gl.readPixels(0, 0, 1, 1, format, gl.UNSIGNED_BYTE, buf);
wtu.glErrorShouldBe(gl, [gl.INVALID_ENUM, gl.INVALID_OPERATION], "Should not be able to read as " + wtu.glEnumToString(gl, format));
}
for (let info of neverValidTypeInfo) {
var type = info.type;
var dest = info.dest;
gl.readPixels(0, 0, 1, 1, gl.RGBA, type, dest);
wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, "Should not be able to read as " + wtu.glEnumToString(gl, type));
}
for (let info of maybeValidTypeInfo) {
var type = info.type;
var dest = info.dest;
gl.readPixels(0, 0, 1, 1, gl.RGBA, type, dest);
wtu.glErrorShouldBe(gl, [gl.INVALID_ENUM, gl.INVALID_OPERATION], "Should not be able to read as " + wtu.glEnumToString(gl, type));
}
var combinations = [
{
format: gl.RGBA,
type: gl.UNSIGNED_BYTE,
dest: new Uint8Array(4),
},
{
format: gl.RGB,
type: gl.UNSIGNED_BYTE,
dest: new Uint8Array(3),
},
{
format: gl.RGB,
type: gl.UNSIGNED_SHORT_5_6_5,
dest: new Uint8Array(3),
},
{
format: gl.RGBA,
type: gl.UNSIGNED_SHORT_5_5_5_1,
dest: new Uint16Array(1),
},
{
format: gl.RGBA,
type: gl.UNSIGNED_SHORT_4_4_4_4,
dest: new Uint16Array(1),
},
{
format: gl.ALPHA,
type: gl.UNSIGNED_BYTE,
dest: new Uint8Array(1),
}
];
if (contextVersion > 1) {
combinations = combinations.concat([
{
format: gl.RED,
type: gl.UNSIGNED_BYTE,
dest: new Uint8Array(1),
},
{
format: gl.RGBA_INTEGER,
type: gl.UNSIGNED_INT,
dest: new Uint32Array(4),
},
{
format: gl.RGBA_INTEGER,
type: gl.INT,
dest: new Int32Array(4),
}
]);
}
debug("");
debug("check invalid combinations of format/type");
var implFormat = gl.getParameter(gl.IMPLEMENTATION_COLOR_READ_FORMAT);
var implType = gl.getParameter(gl.IMPLEMENTATION_COLOR_READ_TYPE);
for (var tt = 0; tt < combinations.length; ++ tt) {
var info = combinations[tt];
var format = info.format;
var type = info.type;
var dest = info.dest;
gl.readPixels(0, 0, 1, 1, format, type, dest);
// Only two format/type parameter pairs are accepted. GL_RGBA/GL_UNSIGNED_BYTE is always
// accepted on default readbuffer. The other acceptable pair can be discovered by querying
// GL_IMPLEMENTATION_COLOR_READ_FORMAT and GL_IMPLEMENTATION_COLOR_READ_TYPE.
if ((format == gl.RGBA && type == gl.UNSIGNED_BYTE) || (format == implFormat && type == implType)) {
wtu.glErrorShouldBe(
gl, gl.NO_ERROR,
"Should be able to read as " + wtu.glEnumToString(gl, format) +
" / " + wtu.glEnumToString(gl, type));
} else {
wtu.glErrorShouldBe(
gl, gl.INVALID_OPERATION,
"Should not be able to read as " + wtu.glEnumToString(gl, format) +
" / " + wtu.glEnumToString(gl, type));
}
}
debug("");
debug("check reading with lots of drawing");
continueTestFunc = continueTestPart3;
width = 1024;
height = 1024;
canvas.width = width;
canvas.height = height;
if (gl.getError() != gl.CONTEXT_LOST_WEBGL) {
continueTestPart3();
}
}
for (var ii = 0; ii < colors.length; ++ii) {
var buf = results[ii];
var color = colors[ii];
actual = [buf[0], buf[1], buf[2], buf[3]];
expected = [color[0], color[1], color[2], color[3]];
shouldBe("actual", "expected");
}
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "there should be no GL errors");
debug("");
finishTest();
function continueTestPart3() {
gl.viewport(0, 0, 1024, 1024);
var program = wtu.setupTexturedQuad(gl);
var loc = gl.getUniformLocation(program, "tex");
gl.disable(gl.BLEND);
gl.disable(gl.DEPTH_TEST);
var colors = [[255, 0, 0, 255], [0, 255, 0, 255], [0, 0, 255, 255]];
var textures = [];
var results = [];
for (var ii = 0; ii < colors.length; ++ii) {
gl.activeTexture(gl.TEXTURE0 + ii);
var tex = gl.createTexture();
wtu.fillTexture(gl, tex, 1, 1, colors[ii]);
textures.push(tex);
}
for (var ii = 0; ii < colors.length; ++ii) {
for (var jj = 0; jj < 300 + ii + 1; ++jj) {
gl.uniform1i(loc, jj % 3);
gl.drawArrays(gl.TRIANGLES, 0, 6);
}
var buf = new Uint8Array(4);
gl.readPixels(512, 512, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, buf);
results.push(buf);
for (var kk = 0; kk < 99; ++kk) {
gl.uniform1i(loc, (jj + kk) % 3);
gl.drawArrays(gl.TRIANGLES, 0, 6);
}
}
for (var ii = 0; ii < colors.length; ++ii) {
var buf = results[ii];
var color = colors[ii];
actual = [buf[0], buf[1], buf[2], buf[3]];
expected = [color[0], color[1], color[2], color[3]];
shouldBe("actual", "expected");
}
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "there should be no GL errors");
}
}
</script>
</body>

Просмотреть файл

@ -1,9 +1,12 @@
--min-version 1.0.4 blending.html
--min-version 1.0.4 canvas-alpha-bug.html
--min-version 1.0.4 --max-version 1.9.9 clipping-wide-points.html
--min-version 1.0.4 color-mask-preserved-during-implicit-clears.html
--min-version 1.0.2 culling.html
--min-version 1.0.4 default-texture-draw-bug.html
draw-arrays-out-of-bounds.html
draw-elements-out-of-bounds.html
--min-version 1.0.4 draw-webgl-to-canvas-2d-repeatedly.html
--min-version 1.0.4 draw-with-changing-start-vertex-bug.html
--min-version 1.0.3 framebuffer-switch.html
--min-version 1.0.3 framebuffer-texture-switch.html
@ -19,6 +22,7 @@ gl-scissor-test.html
more-than-65536-indices.html
multisample-corruption.html
--min-version 1.0.3 negative-one-index.html
out-of-bounds-array-buffers.html
out-of-bounds-index-buffers.html
--min-version 1.0.3 point-no-attributes.html
point-size.html
@ -26,6 +30,7 @@ point-size.html
--min-version 1.0.3 point-with-gl-pointcoord-in-fragment-shader.html
--min-version 1.0.3 polygon-offset.html
--min-version 1.0.4 preservedrawingbuffer-leak.html
--min-version 1.0.4 rendering-sampling-feedback-loop.html
--min-version 1.0.4 scissor-rect-repeated-rendering.html
--min-version 1.0.2 simple.html
triangle.html

Просмотреть файл

@ -0,0 +1,216 @@
<!--
Copyright (c) 2019 The Khronos Group Inc.
Use of this source code is governed by an MIT-style license that can be
found in the LICENSE.txt file.
-->
<!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>
<script id="eVsSrc" type="text/plain">
void main()
{
gl_PointSize = 1.0;
gl_Position = vec4(0, 0, 0, 1);
}
</script>
<script id="eFsSrc" type="text/plain">
precision mediump float;
uniform vec4 uColor;
void main()
{
gl_FragColor = uColor;
}
</script>
</head>
<body>
<div id="description"></div>
<div id="console"></div>
<script>
"use strict";
description('Blending tests');
const wtu = WebGLTestUtils;
function CreateContext() {
const gl = wtu.create3DContext();
gl.viewport(0, 0, 1, 1);
gl.prog = wtu.setupProgram(gl, [eVsSrc.innerHTML, eFsSrc.innerHTML]);
gl.prog.uColor = (() => {
const loc = gl.getUniformLocation(gl.prog, 'uColor');
return x => gl.uniform4fv(loc, x);
})();
gl.useProgram(gl.prog);
gl.prog.uColor([1 / 255, 2 / 255, 3 / 255, 4 / 255]);
gl.drawAndRead = type => {
gl.drawArrays(gl.POINTS, 0, 1);
let ret;
if (type == gl.UNSIGNED_BYTE) {
ret = new Uint8Array(4);
} else if (type == gl.FLOAT) {
ret = new Float32Array(4);
}
gl.readPixels(0, 0, 1, 1, gl.RGBA, type, ret);
return ret;
};
gl.enable(gl.BLEND);
gl.blendFunc(gl.CONSTANT_COLOR, gl.ZERO);
gl.blendColor(10, 1, 1, 1);
return gl;
}
function CreateValidFb(gl, formats) {
const fb = gl.createFramebuffer();
gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
for (let i in formats) {
i = i|0; // Otherwise i is a string. :(
const f = formats[i];
if (!f)
continue;
if (f.length == 1) {
const rb = gl.createRenderbuffer();
gl.bindRenderbuffer(gl.RENDERBUFFER, rb);
gl.renderbufferStorage(gl.RENDERBUFFER, f[0], 1, 1);
gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0+i,
gl.RENDERBUFFER, rb);
continue;
}
if (f.length == 3) {
let internalFormat = f[0];
if (internalFormat === undefined) {
internalFormat = f[1];
}
const tex = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, tex);
gl.texImage2D(gl.TEXTURE_2D, 0, internalFormat, 1,1,0, f[1],f[2], null);
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0+i,
gl.TEXTURE_2D, tex, 0);
continue;
}
throw new Error('Invalid format length: ' + f);
}
const status = gl.checkFramebufferStatus(gl.FRAMEBUFFER);
if (status != gl.FRAMEBUFFER_COMPLETE) {
gl.deleteFramebuffer(fb);
return null;
}
return fb;
}
let was, fb;
const TESTS = [
() => {
debug('');
debug("State queries don't clamp.");
const gl = wtu.create3DContext();
gl.blendColor(1000, 1, 1, 1);
const was = gl.getParameter(gl.BLEND_COLOR);
expectArray(was, [1000, 1, 1, 1]);
},
() => {
debug('');
debug('Blending for RGBA8:');
const gl = CreateContext();
fb = CreateValidFb(gl, [[gl.RGBA8, gl.RGBA, gl.UNSIGNED_BYTE]]);
shouldBeNonNull('fb');
const was = gl.drawAndRead(gl.UNSIGNED_BYTE);
expectArray(was, [1, 2, 3, 4]);
if (gl.getExtension('EXT_color_buffer_float') ||
gl.getExtension('EXT_color_buffer_half_float'))
{
debug('Enable color_buffer_half_float and retest');
gl.blendColor(1000, 1, 1, 1);
const was = gl.drawAndRead(gl.UNSIGNED_BYTE);
expectArray(was, [1, 2, 3, 4]);
}
},
() => {
debug('');
debug('Blending for RGBA16F:');
const gl = CreateContext();
if (gl.blitFramebuffer) {
if (!gl.getExtension('EXT_color_buffer_float')) {
testPassed('Missing ext EXT_color_buffer_float is optional, skipping.');
return;
}
} else {
if (!gl.getExtension('EXT_color_buffer_half_float')) {
testPassed('Missing ext EXT_color_buffer_half_float is optional, skipping.');
return;
}
const ext = gl.getExtension('OES_texture_half_float');
gl.HALF_FLOAT = ext.HALF_FLOAT_OES; // These aren't the same value, but this'll work.
}
fb = CreateValidFb(gl, [[gl.RGBA16F, gl.RGBA, gl.HALF_FLOAT]]);
shouldBeNonNull('fb');
gl.prog.uColor([1, 2, 3, 4]);
const was = gl.drawAndRead(gl.FLOAT);
expectArray(was, [10, 2, 3, 4]);
},
() => {
debug('');
debug('Blending for RGBA32F:');
const gl = CreateContext();
if (gl.blitFramebuffer) {
if (!gl.getExtension('EXT_color_buffer_float')) {
testPassed('Missing ext EXT_color_buffer_float is optional, skipping.');
return;
}
} else {
if (!gl.getExtension('WEBGL_color_buffer_float')) {
testPassed('Missing ext WEBGL_color_buffer_float is optional, skipping.');
return;
}
gl.getExtension('OES_texture_float');
}
fb = CreateValidFb(gl, [[gl.RGBA32F, gl.RGBA, gl.FLOAT]]);
shouldBeNonNull('fb');
gl.prog.uColor([1, 2, 3, 4]);
const was = gl.drawAndRead(gl.FLOAT);
if (!gl.getExtension('EXT_float_blend')) {
wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, 'Should not be able to blend 32F formats.');
return;
}
wtu.glErrorShouldBe(gl, 0, 'Should be able to blend 32F formats.');
expectArray(was, [10, 2, 3, 4]);
},
];
async function Test() {
for (const fn of TESTS) {
await wtu.dispatchPromise(fn);
}
wtu.destroyAllContexts();
finishTest();
}
Test();
var successfullyParsed = true;
</script>
</body>
</html>

Просмотреть файл

@ -0,0 +1,132 @@
<!--
/*
** Copyright (c) 2018 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>ColorMask Must Be Preserved During Implicit Clears</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>
<script>
"use strict";
const wtu = WebGLTestUtils;
const sz = 128;
let frames;
let gl;
let tests = [
{ alpha: false, antialias: false, premultipliedAlpha: false },
{ alpha: false, antialias: false, premultipliedAlpha: true },
{ alpha: false, antialias: true, premultipliedAlpha: false },
{ alpha: false, antialias: true, premultipliedAlpha: true },
];
let currentTest;
let testIndex = 0;
function initTest() {
description();
debug('ColorMask must be preserved during implicit clears of textures.');
debug('Regression test for <a href="http://crbug.com/911918">http://crbug.com/911918</a>');
requestAnimationFrame(nextTest);
}
function nextTest() {
if (testIndex >= tests.length) {
finishTest();
return;
}
frames = 20;
let canvases = document.getElementById('canvases');
let canvas = document.createElement('canvas');
canvas.width = sz;
canvas.height = sz;
canvases.appendChild(canvas);
currentTest = tests[testIndex];
++testIndex;
gl = wtu.create3DContext(canvas, currentTest);
requestAnimationFrame(runTest);
}
function runTest() {
// Create a user-defined framebuffer which has an alpha channel.
let fb = gl.createFramebuffer();
gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
// Set color mask to disable alpha writes. This is important; see below.
gl.colorMask(true, true, true, false);
let tex = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, tex);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, sz, sz, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
// Upload a sub-rectangle. In Chrome, this was lazily clearing level 0 of the
// texture using OpenGL, setting the driver's color mask to (true, true, true,
// true) in the process. Because the user's color mask was set to (true, true,
// true, false) above, incorrect caching code was failing to reset the
// driver's color mask later. On macOS, Chrome implements alpha:false WebGL
// contexts on top of RGBA textures whose alpha channel is cleared to 1.0 and
// where the color mask is set to (true, true, true, false) during all writes.
// This bug was allowing that texture's alpha channel to be destroyed.
gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, new Uint8Array(4));
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex, 0);
// We have to issue one clear to this framebuffer to get the color mask
// latched into the internal caching code.
gl.clear(gl.COLOR_BUFFER_BIT);
// Switch back to default framebuffer.
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
// Set clear color to transparent green.
gl.clearColor(0, 1, 0, 0);
// Clear. Result should be opaque green. Was transparent green when
// bug was encountered.
gl.clear(gl.COLOR_BUFFER_BIT);
wtu.checkCanvasRect(gl, 0, 0, sz, sz,
[ 0, 255, 0, 255 ],
"default framebuffer should be opaque green for " + JSON.stringify(currentTest));
gl.deleteFramebuffer(fb);
gl.deleteTexture(tex);
--frames;
if (frames == 0) {
requestAnimationFrame(nextTest);
} else {
requestAnimationFrame(runTest);
}
}
requestAnimationFrame(initTest);
</script>
</head>
<body>
<div id="description"></div>
<div id="canvases"></div>
<div id="console"></div>
</body>
</html>

Просмотреть файл

@ -0,0 +1,112 @@
<!--
/*
** Copyright (c) 2018 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>Draw WebGL to Canvas2D Repeatedly</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>
<script>
"use strict";
const wtu = WebGLTestUtils;
const sz = 256;
function drawTo2DCanvas(c2, webGLCanvas) {
// Always clear 2D canvas to solid green first.
c2.clearRect(0, 0, sz, sz);
c2.fillStyle = 'rgb(0,255,0)';
c2.fillRect(0, 0, sz, sz);
// Draw WebGL canvas to this canvas.
c2.drawImage(webGLCanvas, 0, 0);
}
function runTest() {
description();
debug('Repeatedly drawing a WebGL canvas to a 2D canvas should only draw the most recently rendered WebGL content.');
debug('Regression test for <a href="http://crbug.com/894021">http://crbug.com/894021</a>');
let c2 = document.getElementById('canvas-2d').getContext('2d');
let webGLCanvas = document.getElementById('canvas-webgl');
let gl = wtu.create3DContext(webGLCanvas, { alpha: true, antialias: false, premultipliedAlpha: true });
let tolerance = 2;
// Clear left half of WebGL canvas to red and right half to
// transparent black.
gl.disable(gl.SCISSOR_TEST);
gl.clearColor(0.0, 0.0, 0.0, 0.0);
gl.clear(gl.COLOR_BUFFER_BIT);
gl.scissor(0, 0, sz / 2, sz);
gl.enable(gl.SCISSOR_TEST);
gl.clearColor(1.0, 0.0, 0.0, 1.0);
gl.clear(gl.COLOR_BUFFER_BIT);
// Draw to 2D canvas.
drawTo2DCanvas(c2, webGLCanvas);
// Clear right half of WebGL canvas to red and left half to
// transparent black.
gl.disable(gl.SCISSOR_TEST);
gl.clearColor(0.0, 0.0, 0.0, 0.0);
gl.clear(gl.COLOR_BUFFER_BIT);
gl.scissor(sz / 2, 0, sz / 2, sz);
gl.enable(gl.SCISSOR_TEST);
gl.clearColor(1.0, 0.0, 0.0, 1.0);
gl.clear(gl.COLOR_BUFFER_BIT);
// Draw to 2D canvas.
drawTo2DCanvas(c2, webGLCanvas);
// Clear WebGL canvas to transparent black.
gl.disable(gl.SCISSOR_TEST);
gl.clearColor(0.0, 0.0, 0.0, 0.0);
gl.clear(gl.COLOR_BUFFER_BIT);
// Draw to 2D canvas.
drawTo2DCanvas(c2, webGLCanvas);
// 2D canvas should be green.
// In the error case, the rendering results from earlier draws were
// being accumulated, so the 2D canvas was ultimately red.
wtu.checkCanvasRect(c2, 0, 0, sz, sz,
[ 0, 255, 0, 255 ],
"should be green",
tolerance);
finishTest();
}
requestAnimationFrame(runTest);
</script>
</head>
<body>
<div id="description"></div>
<div id="console"></div>
<canvas id="canvas-webgl" width="256" height="256"></canvas>
<canvas id="canvas-2d" width="256" height="256"></canvas>
</body>
</html>

Просмотреть файл

@ -0,0 +1,146 @@
<!--
/*
** Copyright (c) 2019 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>
<title>WebGL Out-of-Bounds Array Buffer Conformance Test</title>
</head>
<body>
<canvas id="canvas" width="8" height="8" style="width: 100px; height: 100px;"></canvas>
<div id="description"></div>
<div id="console"></div>
<script id="vsCheckOutOfBounds" type="x-shader/x-vertex">
precision mediump float;
attribute vec2 position;
attribute vec4 vecRandom;
varying vec4 v_color;
// Per the spec, each component can either contain existing contents
// of the buffer or 0.
bool testFloatComponent(float component) {
return (component == 0.2 || component == 0.0);
}
// The last component is additionally allowed to be 1.0.
bool testLastFloatComponent(float component) {
return testFloatComponent(component) || component == 1.0;
}
void main() {
if (testFloatComponent(vecRandom.x) &&
testFloatComponent(vecRandom.y) &&
testFloatComponent(vecRandom.z) &&
testLastFloatComponent(vecRandom.w)) {
v_color = vec4(0.0, 1.0, 0.0, 1.0); // green -- We're good
} else {
v_color = vec4(1.0, 0.0, 0.0, 1.0); // red -- Unexpected value
}
gl_Position = vec4(position, 0.0, 1.0);
}
</script>
<script>
"use strict";
description("This test verifies that out-of-bounds array buffers behave according to spec.");
var wtu = WebGLTestUtils;
var canvas = document.getElementById("canvas");
var gl = wtu.create3DContext(canvas, {antialias: false});
var numberOfQuads = 200;
// Draw out-of-bounds beginning with the start offset passed in.
// Ensure that drawArrays flags either no error or INVALID_OPERATION. In the case of INVALID_OPERATION,
// no canvas pixels can be touched. In the case of NO_ERROR, all written values must either be the
// zero vertex or a value in the vertex buffer. See vsCheckOutOfBounds shader.
function drawAndVerifyOutOfBoundsArrays(gl, first, count) {
gl.clearColor(0.0, 0.0, 1.0, 1.0); // Start with blue to indicate no pixels touched.
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
gl.drawArrays(gl.TRIANGLES, first, count);
var error = gl.getError();
if (error === gl.INVALID_OPERATION) {
testPassed("drawArrays flagged INVALID_OPERATION, which is valid so long as all canvas pixels were not touched.");
wtu.checkCanvas(gl, [0, 0, 255, 255]);
} else if (error === gl.NO_ERROR) {
testPassed("drawArrays flagged NO_ERROR, which is valid so long as all canvas pixels are green.");
wtu.checkCanvas(gl, [0, 255, 0, 255]);
} else {
testFailed("Invalid error flagged by drawArrays. Should be INVALID_OPERATION or NO_ERROR");
}
}
// Create a vertex buffer with 200 properly formed triangle quads. These quads will cover the
// canvas texture such that every single pixel is touched by the fragment shader.
var glQuadBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, glQuadBuffer);
var quadPositions = new Float32Array(numberOfQuads * /*ComponentsPerQuad*/2 * /*VerticesPerQuad*/6);
for (var i = 0; i < quadPositions.length; i += /*ComponentsPerQuad*/2 * /*VerticesPerQuad*/6) {
quadPositions[i+0] = -1.0; // upper left
quadPositions[i+1] = 1.0;
quadPositions[i+2] = 1.0; // upper right
quadPositions[i+3] = 1.0;
quadPositions[i+4] = -1.0; // lower left
quadPositions[i+5] = -1.0;
quadPositions[i+6] = 1.0; // upper right
quadPositions[i+7] = 1.0;
quadPositions[i+8] = 1.0; // lower right
quadPositions[i+9] = -1.0;
quadPositions[i+10] = -1.0; // lower left
quadPositions[i+11] = -1.0;
}
gl.bufferData(gl.ARRAY_BUFFER, quadPositions, gl.STATIC_DRAW);
gl.enableVertexAttribArray(0);
gl.vertexAttribPointer(0, 2, gl.FLOAT, false, 0, 0);
// Create a small vertex buffer with determined-ahead-of-time "random" values (0.2). This buffer will be
// the one read past the end.
var glVertexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, glVertexBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([0.2, 0.2, 0.2, 0.2, 0.2, 0.2]), gl.STATIC_DRAW);
gl.enableVertexAttribArray(1);
gl.vertexAttribPointer(1, 4, gl.FLOAT, false, 0, 0);
// Setup the verification program.
var glProgram = wtu.setupProgram(gl, ["vsCheckOutOfBounds", wtu.simpleVertexColorFragmentShader], ["position", "vecRandom"]);
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Shader and buffer setup should not generate errors");
debug("Test -- Draw off the end of the vertex buffer near the beginning of the out of bounds area.");
drawAndVerifyOutOfBoundsArrays(gl, /*first*/6, /*count*/6);
debug("");
debug("Test -- Draw off the end of the vertex buffer near the end of the out of bounds area.")
drawAndVerifyOutOfBoundsArrays(gl, /*first*/(numberOfQuads - 1) * 6, /*count*/6);
var successfullyParsed = true;
</script>
<script src="../../js/js-test-post.js"></script>
</body>
</html>

Просмотреть файл

@ -139,7 +139,7 @@ gl.vertexAttribPointer(1, 4, gl.FLOAT, false, 0, 0);
// Setup the verification program.
var glProgram = wtu.setupProgram(gl, ["vsCheckOutOfBounds", wtu.simpleVertexColorFragmentShader], ["position", "vecRandom"]);
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Shader and buffer setup should generate errors");
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Shader and buffer setup should not generate errors");
debug("Test -- Index off the end of the vertex buffer near the beginning of the out of bounds area.");
drawAndVerifyOutOfBoundsIndex(gl, /*StartIndex*/4);

Просмотреть файл

@ -0,0 +1,204 @@
<!--
/*
** 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">
<title>WebGL Rendering and Sampling Feedback Loop 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>
<canvas id="example" width="8" height="8"></canvas>
<div id="description"></div>
<div id="console"></div>
<script id="vs100" type="x-shader/x-vertex">
attribute vec4 aPosition;
attribute vec2 aTexCoord;
varying vec2 texCoord;
void main() {
gl_Position = aPosition;
texCoord = aTexCoord;
}
</script>
<script id="fs100" type="x-shader/x-fragment">
#extension GL_EXT_draw_buffers : require
precision mediump float;
uniform sampler2D tex;
varying vec2 texCoord;
void main() {
gl_FragData[0] = texture2D(tex, texCoord);
gl_FragData[1] = texture2D(tex, texCoord);
}
</script>
<script id="fs100-no-ext-draw-buffers" type="x-shader/x-fragment">
precision mediump float;
uniform sampler2D tex;
varying vec2 texCoord;
void main() {
gl_FragData[0] = texture2D(tex, texCoord);
}
</script>
<script id="vs300" type="x-shader/x-vertex">#version 300 es
in highp vec4 aPosition;
in vec2 aTexCoord;
out vec2 texCoord;
void main() {
gl_Position = aPosition;
texCoord = aTexCoord;
}
</script>
<script id="fs300" type="x-shader/x-fragment">#version 300 es
precision mediump float;
uniform sampler2D tex;
in vec2 texCoord;
out vec4 oColor;
void main() {
oColor = texture(tex, texCoord);
}
</script>
<script>
"use strict";
const wtu = WebGLTestUtils;
description("This test verifies the functionality of rendering to the same texture where it samples from.");
const gl = wtu.create3DContext("example");
const width = 8;
const height = 8;
let tex;
let fbo;
let drawBuffers = null;
if (!gl) {
testFailed("WebGL context does not exist");
} else {
testPassed("WebGL context exists");
if (gl.drawBuffers) {
debug("Using webgl2.drawBuffers.");
drawBuffers = (x) => gl.drawBuffers(x);
} else {
const ext = gl.getExtension("WEBGL_draw_buffers");
if (ext) {
debug("Using WEBGL_draw_buffers.drawBuffersWEBGL.");
drawBuffers = (x) => ext.drawBuffersWEBGL(x);
}
}
init();
// The sampling texture is bound to COLOR_ATTACHMENT1 during resource allocation
allocate_resource();
rendering_sampling_feedback_loop(null);
if (drawBuffers) {
rendering_sampling_feedback_loop([gl.NONE]);
rendering_sampling_feedback_loop([gl.COLOR_ATTACHMENT0,
gl.COLOR_ATTACHMENT0+1]);
rendering_sampling_feedback_loop([gl.NONE,
gl.COLOR_ATTACHMENT0+1]);
}
}
function init() {
let shaders = ["vs100", "fs100"];
if (gl.texStorage2D) {
shaders = ["vs300", "fs300"];
} else if (!drawBuffers) {
shaders = ["vs100", "fs100-no-ext-draw-buffers"];
}
const program = wtu.setupProgram(gl, shaders, ["aPosition", "aTexCoord"], [0, 1]);
const positionLoc = gl.getAttribLocation(program, "aPosition");
const texCoordLoc = gl.getAttribLocation(program, "aTexCoord");
if (!program || positionLoc < 0 || texCoordLoc < 0) {
testFailed("Set up program failed");
return;
}
const texLoc = gl.getUniformLocation(program, "tex");
gl.uniform1i(texLoc, 0);
testPassed("Set up program succeeded");
wtu.setupUnitQuad(gl, 0, 1);
gl.viewport(0, 0, width, height);
}
function allocate_resource() {
tex = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, tex);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 2, 2, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
fbo = gl.createFramebuffer();
gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex, 0);
}
function rendering_sampling_feedback_loop(draw_buffers) {
debug("draw_buffers: " + JSON.stringify(draw_buffers));
if (draw_buffers) {
drawBuffers(draw_buffers);
}
// Make sure framebuffer is complete before feedback loop detection
if (gl.checkFramebufferStatus(gl.FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE) {
testFailed("Framebuffer incomplete.");
return;
}
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
wtu.clearAndDrawUnitQuad(gl);
wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "Feedback loop detection should ignore drawBuffers settings.");
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST_MIPMAP_NEAREST);
// The texture will be mipmap incomplete, so feedback cannot occur nor be consistently evaluated.
wtu.clearAndDrawUnitQuad(gl);
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Feedback loop detection should ignore sampled incomplete textures.");
if (draw_buffers) {
drawBuffers([gl.COLOR_ATTACHMENT0]);
}
}
gl.deleteTexture(tex);
gl.deleteFramebuffer(fbo);
var successfullyParsed = true;
</script>
<script src="../../js/js-test-post.js"></script>
</body>
</html>

Просмотреть файл

@ -47,4 +47,5 @@ texture-transparent-pixels-initialized.html
--min-version 1.0.2 mipmap-fbo.html
--min-version 1.0.3 --max-version 1.9.9 texture-fakeblack.html
--min-version 1.0.3 texture-draw-with-2d-and-cube.html
--min-version 1.0.4 texture-video-transparent.html
--min-version 1.0.4 texture-with-flip-y-and-premultiply-alpha.html

Просмотреть файл

@ -111,11 +111,9 @@ function runTest() {
finishTest();
}
loadImageAndStart(runTest);
</script>
</head>
<body>
<body onload="loadImageAndStart(runTest)">
<div id="description"></div>
<div id="console"></div>
<canvas id="canvas" width="40" height="40"></canvas>

Просмотреть файл

@ -58,6 +58,8 @@ if (!gl) {
var tex = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, tex);
wtu.shouldGenerateGLError(gl, [gl.INVALID_ENUM, gl.INVALID_OPERATION],
"gl.compressedTexSubImage2D(gl.TEXTURE_2D, 0, 0, 0, 10, 10, COMPRESSED_RGB_PVRTC_4BPPV1_IMG, new Uint8Array(8));");
wtu.shouldGenerateGLError(gl, gl.INVALID_ENUM, "gl.compressedTexImage2D(gl.TEXTURE_2D, 0, COMPRESSED_RGB_PVRTC_4BPPV1_IMG, 8, 8, 0, new Uint8Array(8))");
wtu.shouldGenerateGLError(gl, gl.INVALID_ENUM, "gl.compressedTexImage2D(gl.TEXTURE_2D, 0, COMPRESSED_RGBA_PVRTC_4BPPV1_IMG, 8, 8, 0, new Uint8Array(8))");
@ -65,6 +67,26 @@ if (!gl) {
wtu.shouldGenerateGLError(gl, gl.NO_ERROR, "formats = gl.getParameter(gl.COMPRESSED_TEXTURE_FORMATS)");
shouldBeNonNull("formats");
shouldBe("formats.length", "0");
wtu.shouldGenerateGLError(gl, gl.NO_ERROR, "gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 4, 4, 0, gl.RGBA, gl.UNSIGNED_BYTE, new Uint8Array(4*4*4));");
wtu.shouldGenerateGLError(gl, gl.INVALID_ENUM,
"gl.compressedTexSubImage2D(gl.TEXTURE_2D, 0, 0, 0, 4, 4, COMPRESSED_RGB_PVRTC_4BPPV1_IMG, new Uint8Array(8));");
// Check too-many and too-few args.
wtu.shouldThrow(gl, false, "too many args", function() {
gl.compressedTexImage2D(gl.TEXTURE_2D, 0, COMPRESSED_RGB_PVRTC_4BPPV1_IMG, 4, 4, 0, new Uint8Array(8), null);
});
wtu.shouldThrow(gl, TypeError, "too few args", function() {
gl.compressedTexImage2D(gl.TEXTURE_2D, 0, COMPRESSED_RGB_PVRTC_4BPPV1_IMG, 4, 4, 0);
});
wtu.shouldThrow(gl, false, "too many args", function() {
gl.compressedTexSubImage2D(gl.TEXTURE_2D, 0, 0, 0, 4, 4, COMPRESSED_RGB_PVRTC_4BPPV1_IMG, new Uint8Array(8), null);
});
wtu.shouldThrow(gl, TypeError, "too few args", function() {
gl.compressedTexSubImage2D(gl.TEXTURE_2D, 0, 0, 0, 4, 4, COMPRESSED_RGB_PVRTC_4BPPV1_IMG);
});
}
var successfullyParsed = true;

Просмотреть файл

@ -136,6 +136,7 @@ function test() {
debug("");
debug("testing: " + info.type);
video = document.createElement("video");
video.muted = true;
var canPlay = true;
if (!video.canPlayType) {
testFailed("video.canPlayType required method missing");

Просмотреть файл

@ -50,6 +50,21 @@ void main()
texCoord = texCoord0;
}
</script>
<script id="trivial-vs" type="text/plain">
void main()
{
gl_Position = vec4(0,0,0,1);
gl_PointSize = 1.0;
}
</script>
<script id="tex-point-fs" type="text/plain">
precision mediump float;
uniform sampler2D uSampler;
void main()
{
gl_FragColor = texture2D(uSampler, vec2(0));
}
</script>
<script>
"use strict";
var gl;
@ -128,6 +143,51 @@ function init()
var y = Math.floor(ii / 2);
wtu.checkCanvasRect(gl, x, y, 1, 1, colors[ii]);
}
debug("");
debug("Swizzle applied to correct ActiveTexture index");
{
const prog = wtu.setupProgram(
gl,
["trivial-vs", "tex-point-fs"]);
prog.uSampler = gl.getUniformLocation(prog, "uSampler");
gl.useProgram(prog);
gl.viewport(0, 0, 1, 1);
gl.activeTexture(gl.TEXTURE0);
wtu.glErrorShouldBe(gl, gl.NO_ERROR);
const tex0_rgba8 = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, tex0_rgba8);
const tex0_rgba8_data = new Uint8Array([10, 20, 30, 40]);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, tex0_rgba8_data);
const tex2_a8 = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, tex2_a8);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.ALPHA, 1, 1, 0, gl.ALPHA, gl.UNSIGNED_BYTE, null);
window.control = new Uint8Array(4);
window.after_swizzle_applied = new Uint8Array(4);
gl.bindTexture(gl.TEXTURE_2D, tex0_rgba8);
gl.drawArrays(gl.POINTS, 0, 1);
gl.readPixels(0, 0, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, window.control);
shouldBeString("window.control", tex0_rgba8_data.toString());
gl.activeTexture(gl.TEXTURE2);
gl.bindTexture(gl.TEXTURE_2D, tex2_a8);
gl.uniform1i(prog.uSampler, 2);
gl.activeTexture(gl.TEXTURE0);
gl.drawArrays(gl.POINTS, 0, 1);
// Firefox would apply the A8-on-R8 swizzle to whatever tex-unit was active.
gl.uniform1i(prog.uSampler, 0);
gl.drawArrays(gl.POINTS, 0, 1);
gl.readPixels(0, 0, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, window.after_swizzle_applied);
shouldBeString("window.after_swizzle_applied", tex0_rgba8_data.toString());
// Firefox would then get 0,0,0,10 here, as the [ZERO,ZERO,ZERO,RED] swizzle was applied to our
// 10,20,30,40 texture.
}
}
init();

Просмотреть файл

@ -152,7 +152,7 @@ function runTest(videoElement)
<canvas id="example" width="64" height="48"></canvas>
<div id="description"></div>
<div id="console"></div>
<video id="vid" style="display:none;">
<video id="vid" style="display:none;" muted>
<source src="../../../resources/npot-video.mp4" type='video/mp4; codecs="avc1.42E01E"' />
<source src="../../../resources/npot-video.webmvp8.webm" type='video/webm; codecs="vp8"' />
<source src="../../../resources/npot-video.theora.ogv" type='video/ogg; codecs="theora"' />

Просмотреть файл

@ -119,7 +119,7 @@ function runNextTest() {
return;
}
}
wtu.dispatchTask(runNextTest);
wtu.dispatchPromise(runNextTest);
}
function testFormatType(t, test) {

Просмотреть файл

@ -0,0 +1,160 @@
<!--
/*
** Copyright (c) 2018 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>Upload texture from animating transparent WebM</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>
<script>
"use strict";
const wtu = WebGLTestUtils;
let gl;
let successfullyParsed;
let video;
initTestingHarness();
function init()
{
description("Upload texture from animating transparent WebM");
const canvas = document.getElementById("example");
gl = wtu.create3DContext(canvas);
const program = wtu.setupTexturedQuad(gl);
const texture = gl.createTexture();
// Bind the texture to texture unit 0
gl.bindTexture(gl.TEXTURE_2D, texture);
const textureLoc = gl.getUniformLocation(program, "tex");
gl.uniform1i(textureLoc, 0);
gl.enable(gl.BLEND);
gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
video = document.getElementById("vid");
const type = 'video/webm; codecs="vp8"';
if (!video.canPlayType) {
testFailed("video.canPlayType required method missing");
finishTest();
return;
}
if (!video.canPlayType(type).replace(/no/, '')) {
debug(info.type + " unsupported");
finishTest();
return;
};
wtu.startPlayingAndWaitForVideo(video, runTest);
}
function runTest(videoElement)
{
let i = 0;
requestAnimationFrame(function frame() {
runOneIteration(videoElement, false);
runOneIteration(videoElement, true);
++i;
if (i < 120) {
requestAnimationFrame(frame);
} else {
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no errors");
finishTest();
}
});
}
function runOneIteration(videoElement, useTexSubImage2D)
{
// Upload the videoElement into the texture
if (useTexSubImage2D) {
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, videoElement);
gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE, videoElement);
} else {
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, videoElement);
}
// Set up texture parameters
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
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);
// Draw the triangles
wtu.clearAndDrawUnitQuad(gl, [255, 0, 0, 255]);
const tolerance = 5;
const red = [255, 0, 0];
const green = [0, 255, 0];
const blue = [0, 0, 255];
// Check the left and right sides. Make sure that EITHER:
// - Left is green and right is transparent-blended-with-red
let leftIsGreen = false, leftIsRed = false, rightIsBlue = false, rightIsRed = false;
let greenRedError = "", redBlueError = "";
wtu.checkCanvasRectColor(gl, 4, 4, 8, 24, green, tolerance,
/* sameFn */ () => { leftIsGreen = true; }, /* differentFn */ m => {}, debug);
wtu.checkCanvasRectColor(gl, 20, 4, 8, 24, red, tolerance,
/* sameFn */ () => { rightIsRed = true; }, /* differentFn */ m => { greenRedError = m; }, debug);
// - Right is blue and left is transparent-blended-with-red
wtu.checkCanvasRectColor(gl, 20, 4, 8, 24, blue, tolerance,
/* sameFn */ () => { rightIsBlue = true; }, /* differentFn */ m => {}, debug);
wtu.checkCanvasRectColor(gl, 4, 4, 8, 24, red, tolerance,
/* sameFn */ () => { leftIsRed = true; }, /* differentFn */ m => { redBlueError = m; }, debug);
if (leftIsGreen) {
if (rightIsRed) {
testPassed("left is green, right is transparent-blended-with-red")
} else {
testFailed("left is green, but: " + greenRedError);
}
} else if (rightIsBlue) {
if (leftIsRed) {
testPassed("right is blue, left is transparent-blended-with-red");
} else {
testFailed("right is blue, but: " + redBlueError);
}
} else {
testFailed("neither left is green nor right is blue")
}
}
</script>
</head>
<body onload="init()">
<canvas id="example" width="32" height="32"></canvas>
<div id="description"></div>
<div id="console"></div>
<video id="vid" style="display:none;">
<source src="../../../resources/transparent-2frames.webm" type='video/webm; codecs="vp8"' />
</video>
</body>
</html>

Просмотреть файл

@ -89,23 +89,22 @@ function resolvable() {
return promise;
}
function fence() {
const promise = resolvable();
function wait() {
return new Promise(res => {
setTimeout(res, 0);
});
}
async function fence() {
const sync = gl.fenceSync(gl.SYNC_GPU_COMMANDS_COMPLETE, 0);
gl.flush();
function check() {
const status = gl.clientWaitSync(sync, 0, 0);
if (status == gl.ALREADY_SIGNALED || status == gl.CONDITION_SATISFIED) {
gl.deleteSync(sync);
promise.resolve();
} else {
setTimeout(check, 0);
}
}
setTimeout(check, 0);
return promise;
let status;
do {
await wait();
status = gl.clientWaitSync(sync, 0, 0);
} while (status != gl.ALREADY_SIGNALED && status != gl.CONDITION_SATISIFIED);
gl.deleteSync(sync);
}
function checkGetBufferSubData(err, data) {
@ -131,6 +130,8 @@ function copyBufferUsingTransformFeedback(src, dst) {
gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, tf);
gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 0, dst);
gl.drawBuffers([gl.NONE]);
gl.enable(gl.RASTERIZER_DISCARD);
gl.beginTransformFeedback(gl.POINTS);
// treats the input and output data as two uint32s
@ -143,120 +144,126 @@ function copyBufferUsingTransformFeedback(src, dst) {
gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, null);
}
Promise.resolve()
.then(() => {
debug("");
debug("write-read");
gl.copyBufferSubData(gl.COPY_READ_BUFFER, gl.COPY_WRITE_BUFFER, 0, 0, 8);
checkGetBufferSubData(gl.NO_ERROR, "srcData");
})
.then(() => {
debug("");
debug("fence-wait-write-read");
return fence().then(() => {
gl.copyBufferSubData(gl.COPY_READ_BUFFER, gl.COPY_WRITE_BUFFER, 0, 0, 8);
checkGetBufferSubData(gl.NO_ERROR, "srcData");
});
})
.then(() => {
debug("");
debug("write-read-fence-wait");
gl.copyBufferSubData(gl.COPY_READ_BUFFER, gl.COPY_WRITE_BUFFER, 0, 0, 8);
checkGetBufferSubData(gl.NO_ERROR, "srcData");
return fence();
})
.then(() => {
debug("");
debug("write-fence-fence-wait-read");
gl.copyBufferSubData(gl.COPY_READ_BUFFER, gl.COPY_WRITE_BUFFER, 0, 0, 8);
fence();
return fence().then(() => {
checkGetBufferSubData(gl.NO_ERROR, "srcData");
});
})
.then(() => {
debug("");
debug("write-fence-wait-read");
gl.copyBufferSubData(gl.COPY_READ_BUFFER, gl.COPY_WRITE_BUFFER, 0, 0, 8);
return fence().then(() => {
checkGetBufferSubData(gl.NO_ERROR, "srcData");
});
})
.then(() => {
debug("");
debug("write-fence-wait-write-read");
gl.copyBufferSubData(gl.ARRAY_BUFFER, gl.COPY_WRITE_BUFFER, 0, 0, 8);
return fence().then(() => {
gl.copyBufferSubData(gl.COPY_READ_BUFFER, gl.COPY_WRITE_BUFFER, 0, 0, 8);
checkGetBufferSubData(gl.NO_ERROR, "srcData");
});
})
.then(() => {
debug("");
debug("write-fence-write-wait-read");
gl.copyBufferSubData(gl.ARRAY_BUFFER, gl.COPY_WRITE_BUFFER, 0, 0, 8);
(async () => {
debug("");
debug("write-read");
gl.copyBufferSubData(gl.COPY_READ_BUFFER, gl.COPY_WRITE_BUFFER, 0, 0, 8);
checkGetBufferSubData(gl.NO_ERROR, "srcData");
debug("");
debug("fence-wait-write-read");
await fence();
gl.copyBufferSubData(gl.COPY_READ_BUFFER, gl.COPY_WRITE_BUFFER, 0, 0, 8);
checkGetBufferSubData(gl.NO_ERROR, "srcData");
debug("");
debug("write-read-fence-wait");
gl.copyBufferSubData(gl.COPY_READ_BUFFER, gl.COPY_WRITE_BUFFER, 0, 0, 8);
checkGetBufferSubData(gl.NO_ERROR, "srcData");
await fence();
debug("");
debug("write-fence-fence-wait-read");
gl.copyBufferSubData(gl.COPY_READ_BUFFER, gl.COPY_WRITE_BUFFER, 0, 0, 8);
fence(); // no await
await fence();
checkGetBufferSubData(gl.NO_ERROR, "srcData");
debug("");
debug("write-fence-wait-read");
gl.copyBufferSubData(gl.COPY_READ_BUFFER, gl.COPY_WRITE_BUFFER, 0, 0, 8);
await fence();
checkGetBufferSubData(gl.NO_ERROR, "srcData");
debug("");
debug("write-fence-wait-write-read");
gl.copyBufferSubData(gl.ARRAY_BUFFER, gl.COPY_WRITE_BUFFER, 0, 0, 8);
await fence();
gl.copyBufferSubData(gl.COPY_READ_BUFFER, gl.COPY_WRITE_BUFFER, 0, 0, 8);
checkGetBufferSubData(gl.NO_ERROR, "srcData");
debug("");
debug("write-fence-write-wait-read");
gl.copyBufferSubData(gl.ARRAY_BUFFER, gl.COPY_WRITE_BUFFER, 0, 0, 8);
{
const p = fence();
gl.copyBufferSubData(gl.COPY_READ_BUFFER, gl.COPY_WRITE_BUFFER, 0, 0, 8);
return p.then(() => {
checkGetBufferSubData(gl.NO_ERROR, "srcData");
});
})
.then(() => {
debug("");
debug("write-fence-transformfeedback-wait-read");
gl.copyBufferSubData(gl.ARRAY_BUFFER, gl.COPY_WRITE_BUFFER, 0, 0, 8);
await p;
}
checkGetBufferSubData(gl.NO_ERROR, "srcData");
debug("");
debug("write-fence-transformfeedback-wait-read");
gl.copyBufferSubData(gl.ARRAY_BUFFER, gl.COPY_WRITE_BUFFER, 0, 0, 8);
{
const p = fence();
gl.bindBuffer(gl.COPY_WRITE_BUFFER, null);
copyBufferUsingTransformFeedback(srcBuffer, readbackBuffer);
gl.bindBuffer(gl.COPY_WRITE_BUFFER, readbackBuffer);
return p.then(() => {
checkGetBufferSubData(gl.NO_ERROR, "srcData");
});
})
.then(() => {
debug("");
debug("write-unbind-fence-wait-bind-read");
gl.bindBuffer(gl.COPY_WRITE_BUFFER, null);
gl.bindBuffer(gl.ARRAY_BUFFER, readbackBuffer);
gl.copyBufferSubData(gl.COPY_READ_BUFFER, gl.ARRAY_BUFFER, 0, 0, 8);
gl.bindBuffer(gl.ARRAY_BUFFER, badBuffer);
return fence().then(() => {
gl.bindBuffer(gl.COPY_WRITE_BUFFER, readbackBuffer);
checkGetBufferSubData(gl.NO_ERROR, "srcData");
});
})
.then(() => {
debug("");
debug("write-fence-wait-delete-read");
gl.copyBufferSubData(gl.ARRAY_BUFFER, gl.COPY_WRITE_BUFFER, 0, 0, 8);
return fence().then(() => {
deleteReadbackBuffer();
checkGetBufferSubData(gl.INVALID_OPERATION, "noData");
recreateReadbackBuffer();
});
})
.then(() => {
debug("");
debug("write-fence-delete-wait-read");
gl.copyBufferSubData(gl.ARRAY_BUFFER, gl.COPY_WRITE_BUFFER, 0, 0, 8);
await p;
}
checkGetBufferSubData(gl.NO_ERROR, "srcData");
debug("");
debug("write-unbind-fence-wait-bind-read");
gl.bindBuffer(gl.COPY_WRITE_BUFFER, null);
gl.bindBuffer(gl.ARRAY_BUFFER, readbackBuffer);
gl.copyBufferSubData(gl.COPY_READ_BUFFER, gl.ARRAY_BUFFER, 0, 0, 8);
gl.bindBuffer(gl.ARRAY_BUFFER, badBuffer);
await fence();
gl.bindBuffer(gl.COPY_WRITE_BUFFER, readbackBuffer);
checkGetBufferSubData(gl.NO_ERROR, "srcData");
debug("");
debug("write-fence-wait-delete-read");
gl.copyBufferSubData(gl.ARRAY_BUFFER, gl.COPY_WRITE_BUFFER, 0, 0, 8);
await fence();
deleteReadbackBuffer();
checkGetBufferSubData(gl.INVALID_OPERATION, "noData");
recreateReadbackBuffer();
debug("");
debug("write-fence-delete-wait-read");
gl.copyBufferSubData(gl.ARRAY_BUFFER, gl.COPY_WRITE_BUFFER, 0, 0, 8);
{
const p = fence();
deleteReadbackBuffer();
return p.then(() => {
checkGetBufferSubData(gl.INVALID_OPERATION, "noData");
recreateReadbackBuffer();
});
})
.then(() => {
await p;
}
checkGetBufferSubData(gl.INVALID_OPERATION, "noData");
recreateReadbackBuffer();
debug("");
debug("write-fence-delete-wait-read");
gl.copyBufferSubData(gl.ARRAY_BUFFER, gl.COPY_WRITE_BUFFER, 0, 0, 8);
deleteReadbackBuffer();
await fence();
checkGetBufferSubData(gl.INVALID_OPERATION, "noData");
recreateReadbackBuffer();
// crbug.com/941930
{
debug("");
debug("write-fence-delete-wait-read");
gl.copyBufferSubData(gl.ARRAY_BUFFER, gl.COPY_WRITE_BUFFER, 0, 0, 8);
debug("write-delete-recreate-fence-wait-read");
gl.copyBufferSubData(gl.COPY_READ_BUFFER, gl.COPY_WRITE_BUFFER, 0, 0, 8);
deleteReadbackBuffer();
return fence().then(() => {
checkGetBufferSubData(gl.INVALID_OPERATION, "noData");
recreateReadbackBuffer();
});
})
.then(finishTest);
recreateReadbackBuffer();
await fence();
checkGetBufferSubData(gl.NO_ERROR, "noData");
debug("");
debug("write-delete-fence-wait-read");
gl.copyBufferSubData(gl.COPY_READ_BUFFER, gl.COPY_WRITE_BUFFER, 0, 0, 8);
{
const p = fence();
deleteReadbackBuffer();
await p;
}
wtu.glErrorShouldBe(gl, gl.NO_ERROR);
}
finishTest();
})();
var successfullyParsed = true;
</script>

Просмотреть файл

@ -1,13 +1,14 @@
ext-color-buffer-float.html
ext-disjoint-timer-query-webgl2.html
--min-version 2.0.1 ext-float-blend.html
promoted-extensions.html
promoted-extensions-in-shaders.html
--min-version 2.0.1 webgl_multiview.html
--min-version 2.0.1 webgl_multiview_depth.html
--min-version 2.0.1 webgl_multiview_draw_buffers.html
--min-version 2.0.1 webgl_multiview_flat_varying.html
--min-version 2.0.1 webgl_multiview_instanced_draw.html
--min-version 2.0.1 webgl_multiview_non_multiview_shaders.html
--min-version 2.0.1 webgl_multiview_single_view_operations.html
--min-version 2.0.1 webgl_multiview_timer_query.html
--min-version 2.0.1 webgl_multiview_transform_feedback.html
--min-version 2.0.1 ovr_multiview2.html
--min-version 2.0.1 ovr_multiview2_depth.html
--min-version 2.0.1 ovr_multiview2_draw_buffers.html
--min-version 2.0.1 ovr_multiview2_flat_varying.html
--min-version 2.0.1 ovr_multiview2_instanced_draw.html
--min-version 2.0.1 ovr_multiview2_non_multiview_shaders.html
--min-version 2.0.1 ovr_multiview2_single_view_operations.html
--min-version 2.0.1 ovr_multiview2_timer_query.html
--min-version 2.0.1 ovr_multiview2_transform_feedback.html

Просмотреть файл

@ -0,0 +1,79 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>WebGL EXT_float_blend 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>
<script src="../../js/tests/ext-float-blend.js"></script>
</head>
<body>
<div id="description"></div>
<div id="console"></div>
<script>
"use strict";
description("This test verifies the functionality of the EXT_float_blend extension, if it is available.");
var wtu = WebGLTestUtils;
var canvas = document.getElementById("canvas");
var gl = wtu.create3DContext(canvas);
var ext = null;
(function(){
const colorBufferFloat = gl.getExtension("EXT_color_buffer_float");
if (!colorBufferFloat) {
testPassed("EXT_color_buffer_float is allowed to be missing.");
return;
}
debug("");
debug("Testing float32 blending without EXT_float_blend");
testExtFloatBlend(gl.RGBA32F);
testExtFloatBlendMRT();
testExtFloatBlendNonFloat32Type();
const floatBlend = gl.getExtension("EXT_float_blend");
if (!floatBlend) {
testPassed("EXT_float_blend is allowed to be missing.");
return;
}
debug("");
debug("Testing that float32 blending is allowed with EXT_float_blend");
testExtFloatBlend(gl.RGBA32F);
testExtFloatBlendMRT();
testExtFloatBlendNonFloat32Type();
})();
debug("");
var successfullyParsed = true;
</script>
<script src="../../js/js-test-post.js"></script>
</body>
</html>
<!--
/*
** Copyright (c) 2019 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.
*/
-->

Просмотреть файл

@ -29,20 +29,20 @@
<html>
<head>
<meta charset="utf-8">
<title>WebGL WEBGL_multiview Conformance Tests</title>
<title>WebGL OVR_multiview2 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>
<script src="../../js/tests/webgl_multiview_util.js"></script>
<script src="../../js/tests/ovr_multiview2_util.js"></script>
<script id="macroFragmentShader" type="x-shader/x-fragment">#version 300 es
precision highp float;
out vec4 my_FragColor;
void main() {
#ifdef GL_OVR_multiview
#ifdef GL_OVR_multiview2
my_FragColor = vec4(0.0, 1.0, 0.0, 1.0);
#else
// Error expected
#error no GL_OVR_multiview;
#error no GL_OVR_multiview2;
#endif
}
</script>
@ -63,12 +63,12 @@ function runExtensionDisabledTest()
debug("Testing queries with extension disabled");
let maxViews = gl.getParameter(0x9631);
wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, "Can't query MAX_VIEWS_OVR without enabling WEBGL_multiview");
wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, "Can't query MAX_VIEWS_OVR without enabling OVR_multiview2");
let baseViewIndex = gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.BACK, 0x9630);
wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, "Can't query FRAMEBUFFER_ATTACHMENT_TEXTURE_BASE_VIEW_INDEX_OVR without enabling WEBGL_multiview");
wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, "Can't query FRAMEBUFFER_ATTACHMENT_TEXTURE_BASE_VIEW_INDEX_OVR without enabling OVR_multiview2");
let numViews = gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.BACK, 0x9632);
wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, "Can't query FRAMEBUFFER_ATTACHMENT_TEXTURE_NUM_VIEWS_OVR without enabling WEBGL_multiview");
wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, "Can't query FRAMEBUFFER_ATTACHMENT_TEXTURE_NUM_VIEWS_OVR without enabling OVR_multiview2");
}
function runQueryTest()
@ -112,17 +112,17 @@ function runInvalidTextureTypeTest()
debug("Testing invalid texture types");
let tex2D = createTextureWithNearestFiltering(gl.TEXTURE_2D);
gl.texStorage2D(gl.TEXTURE_2D, 1, gl.RGBA8, 128, 128);
ext.framebufferTextureMultiviewWEBGL(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, tex2D, 0, 0, 1);
ext.framebufferTextureMultiviewOVR(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, tex2D, 0, 0, 1);
wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "should not be possible to create a multiview framebuffer against a 2D texture");
let texCube = createTextureWithNearestFiltering(gl.TEXTURE_CUBE_MAP);
gl.texStorage2D(gl.TEXTURE_CUBE_MAP, 1, gl.RGBA8, 128, 128);
ext.framebufferTextureMultiviewWEBGL(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, texCube, 0, 0, 1);
ext.framebufferTextureMultiviewOVR(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, texCube, 0, 0, 1);
wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "should not be possible to create a multiview framebuffer against a cube map texture");
let tex3D = createTextureWithNearestFiltering(gl.TEXTURE_3D);
gl.texStorage3D(gl.TEXTURE_3D, 1, gl.RGBA8, 128, 128, 2);
ext.framebufferTextureMultiviewWEBGL(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, tex3D, 0, 0, 2);
ext.framebufferTextureMultiviewOVR(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, tex3D, 0, 0, 2);
wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "should not be possible to create a multiview framebuffer against a 3D texture");
}
@ -143,7 +143,7 @@ function runFramebufferQueryTest(allocateStorage)
}
let setupAndQuery = function(colorTex, levelSet, baseViewIndexSet, numViewsSet) {
ext.framebufferTextureMultiviewWEBGL(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, colorTex, levelSet, baseViewIndexSet, numViewsSet);
ext.framebufferTextureMultiviewOVR(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, colorTex, levelSet, baseViewIndexSet, numViewsSet);
let objectType = gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE);
if (objectType != gl.TEXTURE) {
testFailed('Unexpected FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE ' + wtu.glEnumToString(gl, objectType) + ', should be TEXTURE');
@ -168,7 +168,7 @@ function runFramebufferQueryTest(allocateStorage)
}
let setupSecondAttachmentAndQueryStatus = function(colorTex2, baseViewIndex, numViews, expectedStatus, msg) {
ext.framebufferTextureMultiviewWEBGL(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT1, colorTex2, 0, baseViewIndex, numViews);
ext.framebufferTextureMultiviewOVR(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT1, colorTex2, 0, baseViewIndex, numViews);
let status = gl.checkFramebufferStatus(gl.FRAMEBUFFER);
if (status != expectedStatus) {
testFailed('Framebuffer status: ' + wtu.glEnumToString(gl, status) + ' did not match with the expected value: ' + wtu.glEnumToString(gl, expectedStatus) + ' - ' + msg);
@ -212,7 +212,7 @@ function runFramebufferQueryTest(allocateStorage)
setupSecondAttachmentAndQueryStatus(colorTex2, 1, maxViews - 1, allocateStorage ? gl.FRAMEBUFFER_COMPLETE : gl.FRAMEBUFFER_INCOMPLETE_ATTACHMENT, 'matching baseViewIndex and numViews on different attachments');
if (allocateStorage) {
setupSecondAttachmentAndQueryStatus(colorTex2, 0, maxViews - 1, ext.FRAMEBUFFER_INCOMPLETE_VIEW_TARGETS_OVR, 'baseViewIndex mismatch');
ext.framebufferTextureMultiviewWEBGL(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, colorTex, 0, 0, maxViews);
ext.framebufferTextureMultiviewOVR(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, colorTex, 0, 0, maxViews);
setupSecondAttachmentAndQueryStatus(colorTex2, 0, maxViews - 1, ext.FRAMEBUFFER_INCOMPLETE_VIEW_TARGETS_OVR, 'numViews mismatch');
}
@ -231,18 +231,18 @@ function runInvalidViewsTest()
gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, fb);
let colorTex = createTextureWithNearestFiltering(gl.TEXTURE_2D_ARRAY);
// Don't allocate storage since it's not needed for the validation.
ext.framebufferTextureMultiviewWEBGL(gl.DRAW_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, colorTex, 0, 0, maxViews + 1);
ext.framebufferTextureMultiviewOVR(gl.DRAW_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, colorTex, 0, 0, maxViews + 1);
wtu.glErrorShouldBe(gl, gl.INVALID_VALUE, "Specified too many views");
ext.framebufferTextureMultiviewWEBGL(gl.DRAW_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, colorTex, 0, 0, 0);
ext.framebufferTextureMultiviewOVR(gl.DRAW_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, colorTex, 0, 0, 0);
wtu.glErrorShouldBe(gl, gl.INVALID_VALUE, "Specified zero views");
ext.framebufferTextureMultiviewWEBGL(gl.DRAW_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, colorTex, 0, -1, 2);
ext.framebufferTextureMultiviewOVR(gl.DRAW_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, colorTex, 0, -1, 2);
wtu.glErrorShouldBe(gl, gl.INVALID_VALUE, "Specified negative baseViewIndex");
let colorTex2 = createTextureWithNearestFiltering(gl.TEXTURE_2D_ARRAY);
ext.framebufferTextureMultiviewWEBGL(gl.DRAW_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, colorTex2, 0, maxLayers - maxViews + 1, maxViews);
ext.framebufferTextureMultiviewOVR(gl.DRAW_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, colorTex2, 0, maxLayers - maxViews + 1, maxViews);
// baseViewIndex + numViews = (maxLayers - maxViews + 1) + maxViews = maxLayers + 1
wtu.glErrorShouldBe(gl, gl.INVALID_VALUE, "Specified so many views that baseViewIndex + numViews is greater than MAX_ARRAY_TEXTURE_LAYERS");
ext.framebufferTextureMultiviewWEBGL(gl.DRAW_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, colorTex2, 0, maxLayers - maxViews, maxViews);
ext.framebufferTextureMultiviewOVR(gl.DRAW_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, colorTex2, 0, maxLayers - maxViews, maxViews);
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "baseViewIndex + numViews is exactly MAX_ARRAY_TEXTURE_LAYERS");
}
@ -257,8 +257,8 @@ function runDetachTest()
let fb = gl.createFramebuffer();
gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, fb);
let colorTex = createTextureWithNearestFiltering(gl.TEXTURE_2D_ARRAY);
ext.framebufferTextureMultiviewWEBGL(gl.DRAW_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, colorTex, 0, 0, maxViews);
ext.framebufferTextureMultiviewWEBGL(gl.DRAW_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, null, 0, maxLayers + 1, 0);
ext.framebufferTextureMultiviewOVR(gl.DRAW_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, colorTex, 0, 0, maxViews);
ext.framebufferTextureMultiviewOVR(gl.DRAW_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, null, 0, maxLayers + 1, 0);
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "baseViewIndex and numViews are not validated when detaching");
let objectType = gl.getFramebufferAttachmentParameter(gl.DRAW_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE);
if (objectType != gl.NONE) {
@ -267,7 +267,7 @@ function runDetachTest()
testPassed('FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE was NONE after detach');
}
ext.framebufferTextureMultiviewWEBGL(gl.DRAW_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, colorTex, 0, 0, maxViews);
ext.framebufferTextureMultiviewOVR(gl.DRAW_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, colorTex, 0, 0, maxViews);
gl.framebufferTexture2D(gl.DRAW_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, null, 0);
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Can detach with framebufferTexture2D as well.");
objectType = gl.getFramebufferAttachmentParameter(gl.DRAW_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE);
@ -286,15 +286,15 @@ function runShaderCompileTest(extensionEnabled)
var macroFragmentProgram = wtu.setupProgram(gl, [wtu.simpleVertexShaderESSL300, "macroFragmentShader"], undefined, undefined, true);
if (extensionEnabled) {
if (macroFragmentProgram) {
testPassed("GL_OVR_multiview defined in shaders when extension is enabled");
testPassed("GL_OVR_multiview2 defined in shaders when extension is enabled");
} else {
testFailed("GL_OVR_multiview not defined in shaders when extension is enabled");
testFailed("GL_OVR_multiview2 not defined in shaders when extension is enabled");
}
} else {
if (macroFragmentProgram) {
testFailed("GL_OVR_multiview defined in shaders when extension is disabled");
testFailed("GL_OVR_multiview2 defined in shaders when extension is disabled");
} else {
testPassed("GL_OVR_multiview not defined in shaders when extension disabled");
testPassed("GL_OVR_multiview2 not defined in shaders when extension disabled");
}
}
@ -326,7 +326,7 @@ function runClearTest()
gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
let colorTex = createTextureWithNearestFiltering(gl.TEXTURE_2D_ARRAY);
gl.texStorage3D(gl.TEXTURE_2D_ARRAY, 1, gl.RGBA8, width, height, views);
ext.framebufferTextureMultiviewWEBGL(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, colorTex, 0, 0, views);
ext.framebufferTextureMultiviewOVR(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, colorTex, 0, 0, views);
gl.viewport(0, 0, width, height);
@ -367,7 +367,7 @@ function runFragmentShaderRenderTest()
gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
let colorTex = createTextureWithNearestFiltering(gl.TEXTURE_2D_ARRAY);
gl.texStorage3D(gl.TEXTURE_2D_ARRAY, 1, gl.RGBA8, width, height, views);
ext.framebufferTextureMultiviewWEBGL(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, colorTex, 0, 0, views);
ext.framebufferTextureMultiviewOVR(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, colorTex, 0, 0, views);
gl.viewport(0, 0, width, height);
wtu.drawUnitQuad(gl);
@ -407,7 +407,7 @@ function runVertexShaderRenderTest()
gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
let colorTex = createTextureWithNearestFiltering(gl.TEXTURE_2D_ARRAY);
gl.texStorage3D(gl.TEXTURE_2D_ARRAY, 1, gl.RGBA8, width, height, views);
ext.framebufferTextureMultiviewWEBGL(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, colorTex, 0, 0, views);
ext.framebufferTextureMultiviewOVR(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, colorTex, 0, 0, views);
gl.viewport(0, 0, width, height);
wtu.drawUnitQuad(gl);
@ -448,7 +448,7 @@ function runRealisticUseCaseRenderTest()
gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
let colorTex = createTextureWithNearestFiltering(gl.TEXTURE_2D_ARRAY);
gl.texStorage3D(gl.TEXTURE_2D_ARRAY, 1, gl.RGBA8, width, height, views);
ext.framebufferTextureMultiviewWEBGL(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, colorTex, 0, 0, views);
ext.framebufferTextureMultiviewOVR(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, colorTex, 0, 0, views);
gl.viewport(0, 0, width, height);
@ -480,12 +480,12 @@ function runUniqueObjectTest()
{
debug("");
debug("Testing that getExtension() returns the same object each time");
gl.getExtension("WEBGL_multiview").myProperty = 2;
gl.getExtension("OVR_multiview2").myProperty = 2;
webglHarnessCollectGarbage();
shouldBe('gl.getExtension("WEBGL_multiview").myProperty', '2');
shouldBe('gl.getExtension("OVR_multiview2").myProperty', '2');
}
description("This test verifies the functionality of the WEBGL_multiview extension, if it is available.");
description("This test verifies the functionality of the OVR_multiview2 extension, if it is available.");
debug("");
@ -500,11 +500,11 @@ if (!gl) {
debug("");
if (!gl.getExtension("WEBGL_multiview")) {
testPassed("No WEBGL_multiview support -- this is legal");
if (!gl.getExtension("OVR_multiview2")) {
testPassed("No OVR_multiview2 support -- this is legal");
} else {
testPassed("Successfully enabled WEBGL_multiview extension");
ext = gl.getExtension('WEBGL_multiview');
testPassed("Successfully enabled OVR_multiview2 extension");
ext = gl.getExtension('OVR_multiview2');
runShaderCompileTest(true);

Просмотреть файл

@ -29,20 +29,20 @@
<html>
<head>
<meta charset="utf-8">
<title>WebGL WEBGL_multiview Conformance Tests</title>
<title>WebGL OVR_multiview2 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>
<script src="../../js/tests/webgl_multiview_util.js"></script>
<script src="../../js/tests/ovr_multiview2_util.js"></script>
<script id="macroFragmentShader" type="x-shader/x-fragment">#version 300 es
precision highp float;
out vec4 my_FragColor;
void main() {
#ifdef GL_OVR_multiview
#ifdef GL_OVR_multiview2
my_FragColor = vec4(0.0, 1.0, 0.0, 1.0);
#else
// Error expected
#error no GL_OVR_multiview;
#error no GL_OVR_multiview2;
#endif
}
</script>
@ -81,11 +81,11 @@ function runDepthRenderTest()
gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
let colorTex = createTextureWithNearestFiltering(gl.TEXTURE_2D_ARRAY);
gl.texStorage3D(gl.TEXTURE_2D_ARRAY, 1, gl.RGBA8, width, height, views);
ext.framebufferTextureMultiviewWEBGL(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, colorTex, 0, 0, views);
ext.framebufferTextureMultiviewOVR(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, colorTex, 0, 0, views);
let depthTex = createTextureWithNearestFiltering(gl.TEXTURE_2D_ARRAY);
gl.texStorage3D(gl.TEXTURE_2D_ARRAY, 1, gl.DEPTH32F_STENCIL8, width, height, views);
ext.framebufferTextureMultiviewWEBGL(gl.FRAMEBUFFER, gl.DEPTH_STENCIL_ATTACHMENT, depthTex, 0, 0, views);
ext.framebufferTextureMultiviewOVR(gl.FRAMEBUFFER, gl.DEPTH_STENCIL_ATTACHMENT, depthTex, 0, 0, views);
let expectedStatus = gl.FRAMEBUFFER_COMPLETE;
let status = gl.checkFramebufferStatus(gl.FRAMEBUFFER);
@ -127,7 +127,7 @@ function runDepthRenderTest()
}
}
description("This test verifies drawing to depth buffers with the WEBGL_multiview extension, if it is available.");
description("This test verifies drawing to depth buffers with the OVR_multiview2 extension, if it is available.");
debug("");
@ -138,11 +138,11 @@ if (!gl) {
debug("");
if (!gl.getExtension("WEBGL_multiview")) {
testPassed("No WEBGL_multiview support -- this is legal");
if (!gl.getExtension("OVR_multiview2")) {
testPassed("No OVR_multiview2 support -- this is legal");
} else {
testPassed("Successfully enabled WEBGL_multiview extension");
ext = gl.getExtension('WEBGL_multiview');
testPassed("Successfully enabled OVR_multiview2 extension");
ext = gl.getExtension('OVR_multiview2');
wtu.setupUnitQuad(gl, 0, 1);

Просмотреть файл

@ -29,11 +29,11 @@
<html>
<head>
<meta charset="utf-8">
<title>WebGL WEBGL_multiview Conformance Tests</title>
<title>WebGL OVR_multiview2 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>
<script src="../../js/tests/webgl_multiview_util.js"></script>
<script src="../../js/tests/ovr_multiview2_util.js"></script>
</head>
<body>
<div id="description"></div>
@ -62,7 +62,7 @@ function runDrawBuffersClearTest()
for (let texIndex = 0; texIndex < colorTex.length; ++texIndex) {
colorTex[texIndex] = createTextureWithNearestFiltering(gl.TEXTURE_2D_ARRAY);
gl.texStorage3D(gl.TEXTURE_2D_ARRAY, 1, gl.RGBA8, width, height, views);
ext.framebufferTextureMultiviewWEBGL(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0 + texIndex, colorTex[texIndex], 0, 0, views);
ext.framebufferTextureMultiviewOVR(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0 + texIndex, colorTex[texIndex], 0, 0, views);
drawBuffers[texIndex] = gl.COLOR_ATTACHMENT0 + texIndex;
}
@ -102,7 +102,7 @@ function runDrawBuffersRenderTest()
for (let texIndex = 0; texIndex < colorTex.length; ++texIndex) {
colorTex[texIndex] = createTextureWithNearestFiltering(gl.TEXTURE_2D_ARRAY);
gl.texStorage3D(gl.TEXTURE_2D_ARRAY, 1, gl.RGBA8, width, height, views);
ext.framebufferTextureMultiviewWEBGL(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0 + texIndex, colorTex[texIndex], 0, 0, views);
ext.framebufferTextureMultiviewOVR(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0 + texIndex, colorTex[texIndex], 0, 0, views);
drawBuffers[texIndex] = gl.COLOR_ATTACHMENT0 + texIndex;
}
@ -147,7 +147,7 @@ function runDrawBuffersRenderTest()
}
}
description("This test verifies the functionality of the WEBGL_multiview extension when used with multiple draw buffers, if it is available.");
description("This test verifies the functionality of the OVR_multiview2 extension when used with multiple draw buffers, if it is available.");
debug("");
@ -156,11 +156,11 @@ if (!gl) {
} else {
testPassed("WebGL context exists");
if (!gl.getExtension("WEBGL_multiview")) {
testPassed("No WEBGL_multiview support -- this is legal");
if (!gl.getExtension("OVR_multiview2")) {
testPassed("No OVR_multiview2 support -- this is legal");
} else {
testPassed("Successfully enabled WEBGL_multiview extension");
ext = gl.getExtension('WEBGL_multiview');
testPassed("Successfully enabled OVR_multiview2 extension");
ext = gl.getExtension('OVR_multiview2');
runDrawBuffersClearTest();

Просмотреть файл

@ -29,11 +29,11 @@
<html>
<head>
<meta charset="utf-8">
<title>WebGL WEBGL_multiview Conformance Tests</title>
<title>WebGL OVR_multiview2 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>
<script src="../../js/tests/webgl_multiview_util.js"></script>
<script src="../../js/tests/ovr_multiview2_util.js"></script>
</head>
<body>
<div id="description"></div>
@ -69,7 +69,7 @@ function runFlatVaryingTest()
gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
let colorTex = createTextureWithNearestFiltering(gl.TEXTURE_2D_ARRAY);
gl.texStorage3D(gl.TEXTURE_2D_ARRAY, 1, gl.RGBA8, width, height, views);
ext.framebufferTextureMultiviewWEBGL(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, colorTex, 0, 0, views);
ext.framebufferTextureMultiviewOVR(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, colorTex, 0, 0, views);
gl.viewport(0, 0, width, height);
wtu.drawUnitQuad(gl);
@ -84,7 +84,7 @@ function runFlatVaryingTest()
}
}
description("This test verifies that flat varyings work in multiview shaders using WEBGL_multiview extension, if it is available.");
description("This test verifies that flat varyings work in multiview shaders using OVR_multiview2 extension, if it is available.");
debug("");
@ -93,11 +93,11 @@ if (!gl) {
} else {
testPassed("WebGL context exists");
if (!gl.getExtension("WEBGL_multiview")) {
testPassed("No WEBGL_multiview support -- this is legal");
if (!gl.getExtension("OVR_multiview2")) {
testPassed("No OVR_multiview2 support -- this is legal");
} else {
testPassed("Successfully enabled WEBGL_multiview extension");
ext = gl.getExtension('WEBGL_multiview');
testPassed("Successfully enabled OVR_multiview2 extension");
ext = gl.getExtension('OVR_multiview2');
wtu.setupUnitQuad(gl, 0, 1);

Просмотреть файл

@ -29,11 +29,11 @@
<html>
<head>
<meta charset="utf-8">
<title>WebGL WEBGL_multiview Conformance Tests</title>
<title>WebGL OVR_multiview2 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>
<script src="../../js/tests/webgl_multiview_util.js"></script>
<script src="../../js/tests/ovr_multiview2_util.js"></script>
</head>
<body>
<div id="description"></div>
@ -70,7 +70,7 @@ function runInstancedDrawTest()
gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
let colorTex = createTextureWithNearestFiltering(gl.TEXTURE_2D_ARRAY);
gl.texStorage3D(gl.TEXTURE_2D_ARRAY, 1, gl.RGBA8, width, height, views);
ext.framebufferTextureMultiviewWEBGL(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, colorTex, 0, 0, views);
ext.framebufferTextureMultiviewOVR(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, colorTex, 0, 0, views);
gl.viewport(0, 0, width, height);
gl.drawArraysInstanced(gl.TRIANGLES, 0, 6, 2);
@ -96,7 +96,7 @@ function runInstancedDrawTest()
}
}
description("This test verifies instanced draws together with the WEBGL_multiview extension, if it is available.");
description("This test verifies instanced draws together with the OVR_multiview2 extension, if it is available.");
debug("");
@ -105,11 +105,11 @@ if (!gl) {
} else {
testPassed("WebGL context exists");
if (!gl.getExtension("WEBGL_multiview")) {
testPassed("No WEBGL_multiview support -- this is legal");
if (!gl.getExtension("OVR_multiview2")) {
testPassed("No OVR_multiview2 support -- this is legal");
} else {
testPassed("Successfully enabled WEBGL_multiview extension");
ext = gl.getExtension('WEBGL_multiview');
testPassed("Successfully enabled OVR_multiview2 extension");
ext = gl.getExtension('OVR_multiview2');
wtu.setupUnitQuad(gl, 0, 1);

Просмотреть файл

@ -29,11 +29,11 @@
<html>
<head>
<meta charset="utf-8">
<title>WebGL WEBGL_multiview Conformance Tests</title>
<title>WebGL OVR_multiview2 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>
<script src="../../js/tests/webgl_multiview_util.js"></script>
<script src="../../js/tests/ovr_multiview2_util.js"></script>
</head>
<body>
<div id="description"></div>
@ -66,7 +66,7 @@ function runNonMultiviewShaderTest()
gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
let colorTex = createTextureWithNearestFiltering(gl.TEXTURE_2D_ARRAY);
gl.texStorage3D(gl.TEXTURE_2D_ARRAY, 1, gl.RGBA8, width, height, depth);
ext.framebufferTextureMultiviewWEBGL(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, colorTex, 0, 0, 1);
ext.framebufferTextureMultiviewOVR(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, colorTex, 0, 0, 1);
gl.viewport(0, 0, width, height);
@ -79,12 +79,12 @@ function runNonMultiviewShaderTest()
gl.framebufferTextureLayer(gl.READ_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, colorTex, 0, 0);
wtu.checkCanvasRect(gl, 0, 0, width, height, [0, 255, 0, 255], 'view 0 should be green');
ext.framebufferTextureMultiviewWEBGL(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, colorTex, 0, 0, 2);
ext.framebufferTextureMultiviewOVR(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, colorTex, 0, 0, 2);
wtu.drawUnitQuad(gl);
wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "draw should generate an INVALID_OPERATION error when using a non-multiview shader and the number of views is > 1");
}
description("This test verifies that non-multiview shaders work correctly with WEBGL_multiview extension, if it is available.");
description("This test verifies that non-multiview shaders work correctly with OVR_multiview2 extension, if it is available.");
debug("");
@ -93,11 +93,11 @@ if (!gl) {
} else {
testPassed("WebGL context exists");
if (!gl.getExtension("WEBGL_multiview")) {
testPassed("No WEBGL_multiview support -- this is legal");
if (!gl.getExtension("OVR_multiview2")) {
testPassed("No OVR_multiview2 support -- this is legal");
} else {
testPassed("Successfully enabled WEBGL_multiview extension");
ext = gl.getExtension('WEBGL_multiview');
testPassed("Successfully enabled OVR_multiview2 extension");
ext = gl.getExtension('OVR_multiview2');
wtu.setupUnitQuad(gl, 0, 1);

Просмотреть файл

@ -29,11 +29,11 @@
<html>
<head>
<meta charset="utf-8">
<title>WebGL WEBGL_multiview Conformance Tests</title>
<title>WebGL OVR_multiview2 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>
<script src="../../js/tests/webgl_multiview_util.js"></script>
<script src="../../js/tests/ovr_multiview2_util.js"></script>
</head>
<body>
<div id="description"></div>
@ -58,7 +58,7 @@ function runSingleViewReadTest()
gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
let colorTex = createTextureWithNearestFiltering(gl.TEXTURE_2D_ARRAY);
gl.texStorage3D(gl.TEXTURE_2D_ARRAY, 1, gl.RGBA8, width, height, depth);
ext.framebufferTextureMultiviewWEBGL(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, colorTex, 0, 0, 1);
ext.framebufferTextureMultiviewOVR(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, colorTex, 0, 0, 1);
gl.viewport(0, 0, width, height);
gl.clearColor(0.0, 1.0, 1.0, 1.0);
@ -73,7 +73,7 @@ function runSingleViewReadTest()
gl.getError();
// Also test for the error case with two views
ext.framebufferTextureMultiviewWEBGL(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, colorTex, 0, 0, 2);
ext.framebufferTextureMultiviewOVR(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, colorTex, 0, 0, 2);
gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, buf);
wtu.glErrorShouldBe(gl, gl.INVALID_FRAMEBUFFER_OPERATION, "should be an error to read from a framebuffer with two views");
}
@ -91,7 +91,7 @@ function runSingleViewBlitTest()
gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
let colorTex = createTextureWithNearestFiltering(gl.TEXTURE_2D_ARRAY);
gl.texStorage3D(gl.TEXTURE_2D_ARRAY, 1, gl.RGBA8, width, height, depth);
ext.framebufferTextureMultiviewWEBGL(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, colorTex, 0, 0, 1);
ext.framebufferTextureMultiviewOVR(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, colorTex, 0, 0, 1);
gl.viewport(0, 0, width, height);
gl.clearColor(0.0, 1.0, 1.0, 1.0);
@ -116,7 +116,7 @@ function runSingleViewBlitTest()
// Also test for the error case with two views
gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
ext.framebufferTextureMultiviewWEBGL(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, colorTex, 0, 0, 2);
ext.framebufferTextureMultiviewOVR(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, colorTex, 0, 0, 2);
gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, null);
gl.blitFramebuffer(0, 0, width, height, 0, 0, width, height, gl.COLOR_BUFFER_BIT, gl.NEAREST);
wtu.glErrorShouldBe(gl, gl.INVALID_FRAMEBUFFER_OPERATION, "should be an error to blit from a framebuffer with two views");
@ -135,7 +135,7 @@ function runSingleViewCopyTexImage2DTest()
gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
let colorTex = createTextureWithNearestFiltering(gl.TEXTURE_2D_ARRAY);
gl.texStorage3D(gl.TEXTURE_2D_ARRAY, 1, gl.RGBA8, width, height, depth);
ext.framebufferTextureMultiviewWEBGL(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, colorTex, 0, 0, 1);
ext.framebufferTextureMultiviewOVR(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, colorTex, 0, 0, 1);
gl.viewport(0, 0, width, height);
gl.clearColor(0.0, 1.0, 1.0, 1.0);
@ -154,7 +154,7 @@ function runSingleViewCopyTexImage2DTest()
// Also test for the error case with two views
gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
ext.framebufferTextureMultiviewWEBGL(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, colorTex, 0, 0, 2);
ext.framebufferTextureMultiviewOVR(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, colorTex, 0, 0, 2);
gl.bindTexture(gl.TEXTURE_2D, copyTargetTex);
gl.copyTexImage2D(gl.TEXTURE_2D, 0, gl.RGBA8, 0, 0, width, height, 0);
wtu.glErrorShouldBe(gl, gl.INVALID_FRAMEBUFFER_OPERATION, "should be an error to copy from a framebuffer with two views");
@ -173,7 +173,7 @@ function runSingleViewCopyTexSubImage2DTest()
gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
let colorTex = createTextureWithNearestFiltering(gl.TEXTURE_2D_ARRAY);
gl.texStorage3D(gl.TEXTURE_2D_ARRAY, 1, gl.RGBA8, width, height, depth);
ext.framebufferTextureMultiviewWEBGL(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, colorTex, 0, 0, 1);
ext.framebufferTextureMultiviewOVR(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, colorTex, 0, 0, 1);
gl.viewport(0, 0, width, height);
gl.clearColor(0.0, 1.0, 1.0, 1.0);
@ -193,7 +193,7 @@ function runSingleViewCopyTexSubImage2DTest()
// Also test for the error case with two views
gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
ext.framebufferTextureMultiviewWEBGL(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, colorTex, 0, 0, 2);
ext.framebufferTextureMultiviewOVR(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, colorTex, 0, 0, 2);
gl.bindTexture(gl.TEXTURE_2D, copyTargetTex);
gl.copyTexSubImage2D(gl.TEXTURE_2D, 0, 0, 0, 0, 0, width, height);
wtu.glErrorShouldBe(gl, gl.INVALID_FRAMEBUFFER_OPERATION, "should be an error to copy from a framebuffer with two views");
@ -212,7 +212,7 @@ function runSingleViewCopyTexSubImage3DTest()
gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
let colorTex = createTextureWithNearestFiltering(gl.TEXTURE_2D_ARRAY);
gl.texStorage3D(gl.TEXTURE_2D_ARRAY, 1, gl.RGBA8, width, height, depth);
ext.framebufferTextureMultiviewWEBGL(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, colorTex, 0, 0, 1);
ext.framebufferTextureMultiviewOVR(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, colorTex, 0, 0, 1);
gl.viewport(0, 0, width, height);
gl.clearColor(0.0, 1.0, 1.0, 1.0);
@ -232,13 +232,13 @@ function runSingleViewCopyTexSubImage3DTest()
// Also test for the error case with two views
gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
ext.framebufferTextureMultiviewWEBGL(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, colorTex, 0, 0, 2);
ext.framebufferTextureMultiviewOVR(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, colorTex, 0, 0, 2);
gl.bindTexture(gl.TEXTURE_3D, copyTargetTex);
gl.copyTexSubImage3D(gl.TEXTURE_3D, 0, 0, 0, 0, 0, 0, width, height);
wtu.glErrorShouldBe(gl, gl.INVALID_FRAMEBUFFER_OPERATION, "should be an error to copy from a framebuffer with two views");
}
description("This test verifies that framebuffers with only one view can be read from with WEBGL_multiview extension, if it is available.");
description("This test verifies that framebuffers with only one view can be read from with OVR_multiview2 extension, if it is available.");
debug("");
@ -247,11 +247,11 @@ if (!gl) {
} else {
testPassed("WebGL context exists");
if (!gl.getExtension("WEBGL_multiview")) {
testPassed("No WEBGL_multiview support -- this is legal");
if (!gl.getExtension("OVR_multiview2")) {
testPassed("No OVR_multiview2 support -- this is legal");
} else {
testPassed("Successfully enabled WEBGL_multiview extension");
ext = gl.getExtension('WEBGL_multiview');
testPassed("Successfully enabled OVR_multiview2 extension");
ext = gl.getExtension('OVR_multiview2');
runSingleViewReadTest();

Просмотреть файл

@ -29,11 +29,11 @@
<html>
<head>
<meta charset="utf-8">
<title>WebGL WEBGL_multiview Conformance Tests</title>
<title>WebGL OVR_multiview2 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>
<script src="../../js/tests/webgl_multiview_util.js"></script>
<script src="../../js/tests/ovr_multiview2_util.js"></script>
</head>
<body>
<div id="description"></div>
@ -60,7 +60,7 @@ function runClearTest()
gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
let colorTex = createTextureWithNearestFiltering(gl.TEXTURE_2D_ARRAY);
gl.texStorage3D(gl.TEXTURE_2D_ARRAY, 1, gl.RGBA8, width, height, views);
ext.framebufferTextureMultiviewWEBGL(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, colorTex, 0, 0, views);
ext.framebufferTextureMultiviewOVR(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, colorTex, 0, 0, views);
gl.viewport(0, 0, width, height);
@ -108,7 +108,7 @@ function runFragmentShaderRenderTest()
gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
let colorTex = createTextureWithNearestFiltering(gl.TEXTURE_2D_ARRAY);
gl.texStorage3D(gl.TEXTURE_2D_ARRAY, 1, gl.RGBA8, width, height, views);
ext.framebufferTextureMultiviewWEBGL(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, colorTex, 0, 0, views);
ext.framebufferTextureMultiviewOVR(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, colorTex, 0, 0, views);
gl.viewport(0, 0, width, height);
@ -130,7 +130,7 @@ function runFragmentShaderRenderTest()
}
}
description("This test verifies the functionality of the WEBGL_multiview extension and its interaction with EXT_disjoint_timer_query_webgl2, if it is available.");
description("This test verifies the functionality of the OVR_multiview2 extension and its interaction with EXT_disjoint_timer_query_webgl2, if it is available.");
debug("");
@ -139,11 +139,11 @@ if (!gl) {
} else {
testPassed("WebGL context exists");
if (!gl.getExtension("WEBGL_multiview") || !gl.getExtension("EXT_disjoint_timer_query_webgl2")) {
testPassed("No WEBGL_multiview support or no EXT_disjoint_timer_query_webgl2 support -- this is legal");
if (!gl.getExtension("OVR_multiview2") || !gl.getExtension("EXT_disjoint_timer_query_webgl2")) {
testPassed("No OVR_multiview2 support or no EXT_disjoint_timer_query_webgl2 support -- this is legal");
} else {
testPassed("Successfully enabled WEBGL_multiview and EXT_disjoint_timer_query_webgl2 extensions");
ext = gl.getExtension('WEBGL_multiview');
testPassed("Successfully enabled OVR_multiview2 and EXT_disjoint_timer_query_webgl2 extensions");
ext = gl.getExtension('OVR_multiview2');
queryExt = gl.getExtension('EXT_disjoint_timer_query_webgl2');
runClearTest();

Просмотреть файл

@ -29,11 +29,11 @@
<html>
<head>
<meta charset="utf-8">
<title>WebGL WEBGL_multiview Conformance Tests</title>
<title>WebGL OVR_multiview2 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>
<script src="../../js/tests/webgl_multiview_util.js"></script>
<script src="../../js/tests/ovr_multiview2_util.js"></script>
</head>
<body>
<div id="description"></div>
@ -70,7 +70,7 @@ function runTransformFeedbackTest()
gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
let colorTex = createTextureWithNearestFiltering(gl.TEXTURE_2D_ARRAY);
gl.texStorage3D(gl.TEXTURE_2D_ARRAY, 1, gl.RGBA8, width, height, views);
ext.framebufferTextureMultiviewWEBGL(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, colorTex, 0, 0, views);
ext.framebufferTextureMultiviewOVR(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, colorTex, 0, 0, views);
let xfb = gl.createTransformFeedback();
gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, xfb);
@ -88,14 +88,14 @@ function runTransformFeedbackTest()
gl.pauseTransformFeedback();
wtu.drawUnitQuad(gl);
wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "rendering to a multiview framebuffer with more than one view when there's an active transform feedback should result in invalid operation even if the transform feedback is paused");
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no errors from draw when rendering to a multiview framebuffer with more than one view when there's an active paused transform feedback");
let readFb = gl.createFramebuffer();
gl.bindFramebuffer(gl.READ_FRAMEBUFFER, readFb);
for (let viewIndex = 0; viewIndex < views; ++viewIndex) {
gl.framebufferTextureLayer(gl.READ_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, colorTex, 0, viewIndex);
let expectedColor = [0, 0, 0, 0];
wtu.checkCanvasRect(gl, 0, 0, width, height, expectedColor, 'view ' + viewIndex + ' should be untouched');
let expectedColor = getExpectedColor(viewIndex);
wtu.checkCanvasRect(gl, 0, 0, width, height, expectedColor, 'view ' + viewIndex + ' should be colored ' + expectedColor);
}
gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, null);
@ -116,7 +116,7 @@ function runTransformFeedbackTest()
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no errors from ending transform feedback");
}
description("This test verifies interaction between transform feedback and the WEBGL_multiview extension, if it is available.");
description("This test verifies interaction between transform feedback and the OVR_multiview2 extension, if it is available.");
debug("");
@ -125,11 +125,11 @@ if (!gl) {
} else {
testPassed("WebGL context exists");
if (!gl.getExtension("WEBGL_multiview")) {
testPassed("No WEBGL_multiview support -- this is legal");
if (!gl.getExtension("OVR_multiview2")) {
testPassed("No OVR_multiview2 support -- this is legal");
} else {
testPassed("Successfully enabled WEBGL_multiview extension");
ext = gl.getExtension('WEBGL_multiview');
testPassed("Successfully enabled OVR_multiview2 extension");
ext = gl.getExtension('OVR_multiview2');
wtu.setupUnitQuad(gl, 0, 1);

Просмотреть файл

@ -35,7 +35,7 @@ instanced-arrays.html
--min-version 2.0.1 multisampling-fragment-evaluation.html
out-of-bounds-index-buffers-after-copying.html
--min-version 2.0.1 read-draw-when-missing-image.html
--min-version 2.0.1 rendering-sampling-feedback-loop.html
rgb-format-support.html
uniform-block-buffer-size.html
--min-version 2.0.1 texture-switch-performance.html
--min-version 2.0.1 vertex-id.html

Просмотреть файл

@ -48,13 +48,17 @@ description("This test verifies the behavior of blitFramebuffer when resolving d
debug("Regression test for <a href='http://crbug.com/699566'>http://crbug.com/699566</a>");
function runTest(testParams) {
// Assume a square framebuffer. Doesn't need to match the size of the canvas, necessarily.
let sz = 64;
const sz = 64;
if (testParams.multisampled === undefined) {
testParams.multisampled = true;
}
debug('');
debug('Testing with alpha = ' + testParams.attribs.alpha +
', antialias = ' + testParams.attribs.antialias +
', internalformat = ' + testParams.internalformat);
', internalformat = ' + testParams.internalformat +
', multisampled = ' + testParams.multisampled);
var canvas = document.createElement('canvas');
canvas.width = sz;
@ -63,10 +67,13 @@ function runTest(testParams) {
var gl = wtu.create3DContext(canvas, testParams.attribs, 2);
// Find the supported samples for a multisampled renderbuffer of the appropriate internal format.
let samples = gl.getInternalformatParameter(gl.RENDERBUFFER, gl[testParams.internalformat], gl.SAMPLES);
if (!samples || !samples.length) {
testFailed("At least one multisampled format is required to be supported");
return;
let samples = [0];
if (testParams.multisampled) {
samples = gl.getInternalformatParameter(gl.RENDERBUFFER, gl[testParams.internalformat], gl.SAMPLES);
if (!samples || !samples.length) {
testFailed("At least one multisampled format is required to be supported");
return;
}
}
// Create a framebuffer with a multisampled renderbuffer.
@ -122,10 +129,33 @@ var tests = [
antialias: false,
},
internalformat: 'RGB8',
clearColor: [ 0.0, 1.0, 0.0, 1.0 ],
clearColor: [ 0.0, 1.0, 0.0, 0.5 ],
resultColor: [ 0, 255, 0, 255 ],
shouldSucceed: true,
},
// No-alpha, no-antialias, RGBA8 source
{
attribs: {
alpha: false,
antialias: false,
},
internalformat: 'RGBA8',
clearColor: [ 0.0, 1.0, 0.0, 0.5 ],
resultColor: [ 0, 255, 0, 255 ],
shouldSucceed: false,
},
// No-alpha, no-antialias, RGBA8 source, single-sampled blit
{
attribs: {
alpha: false,
antialias: false,
},
internalformat: 'RGBA8',
clearColor: [ 0.0, 1.0, 0.0, 0.5 ],
resultColor: [ 0, 255, 0, 255 ],
shouldSucceed: true,
multisampled: false,
},
// Alpha, no-antialias, RGB8 source
{
attribs: {

Просмотреть файл

@ -109,8 +109,15 @@ function init() {
tex1 = gl.createTexture();
tex2 = gl.createTexture();
wtu.fillTexture(gl, tex0, width, height, [0x0, 0xff, 0x0, 0xff], 0, gl.RGBA, gl.UNSIGNED_BYTE, gl.RGBA);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
wtu.fillTexture(gl, tex1, width, height, [0x80], 0, gl.DEPTH_COMPONENT, gl.UNSIGNED_INT, gl.DEPTH_COMPONENT16);
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_COMPARE_MODE, gl.COMPARE_REF_TO_TEXTURE);
wtu.fillTexture(gl, tex2, width, height, [0x40], 0, gl.DEPTH_STENCIL, gl.UNSIGNED_INT_24_8, gl.DEPTH24_STENCIL8);
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_COMPARE_MODE, gl.COMPARE_REF_TO_TEXTURE);
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Succeed to create textures.");
fbo = gl.createFramebuffer();
@ -126,19 +133,18 @@ function detect_depth_stencil_feedback_loop() {
testFailed("Framebuffer incomplete.");
return;
}
gl.enable(gl.DEPTH_TEST);
wtu.clearAndDrawUnitQuad(gl);
wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "The test samples from a image. The same image is used as depth buffer during rendering.");
gl.depthMask(gl.FALSE);
wtu.clearAndDrawUnitQuad(gl);
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "The test sampls from a image. The same image is used as depth buffer. But depth mask is false.");
wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "The test samples from a image. The same image is used as depth buffer. A feedback loop is formed regardless of the status of depth mask.");
gl.depthMask(gl.TRUE);
gl.disable(gl.DEPTH_TEST);
wtu.clearAndDrawUnitQuad(gl);
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "The test samples from a image. The same image is used as depth buffer. But depth test is not enabled during rendering.");
wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "The test samples from a image. The same image is used as depth buffer. A feedback loop is formed regardless of whether the depth test is enabled.");
// Test rendering and sampling feedback loop for stencil buffer
gl.bindTexture(gl.TEXTURE_2D, tex2);
@ -155,12 +161,12 @@ function detect_depth_stencil_feedback_loop() {
gl.stencilMask(0x0);
wtu.clearAndDrawUnitQuad(gl);
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "The test sampls from a image. The same image is used as stencil buffer. But stencil mask is zero.");
wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "The test sampls from a image. The same image is used as stencil buffer. A feedback loop is formed regardless of the status of stencil mask.");
gl.stencilMask(0xffff);
gl.disable(gl.STENCIL_TEST);
wtu.clearAndDrawUnitQuad(gl);
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "The test samples from a image. The same image is used as stencil buffer. But stencil test is not enabled during rendering.");
wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "The test samples from a image. The same image is used as stencil buffer. A feedback loop is formed regardless of whether the stencil test is enabled.");
}
function deinit() {

Просмотреть файл

@ -358,8 +358,14 @@ function runDrawTests() {
// GLES3 spec section 3.9.2 Shader Outputs
debug("test that gl_FragColor only writes to color number zero");
gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
gl.drawBuffers([gl.COLOR_ATTACHMENT0]);
gl.drawBuffers(bufs);
gl.useProgram(blueProgramESSL1);
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "there should be no errors");
wtu.drawUnitQuad(gl);
wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "Active draw buffers with missing frag outputs.");
gl.drawBuffers([gl.COLOR_ATTACHMENT0]);
wtu.drawUnitQuad(gl);
drawBuffersUtils.checkAttachmentsForColorFn(attachments, function(attachment, index) {
@ -370,8 +376,14 @@ function runDrawTests() {
// See GLSL ES Spec 3.00.4, Section 4.3.8.2, Output Layout Qualifiers.
debug("test that an OpenGL ES Shading Language 3.00 shader with a single output color defaults to color number zero");
gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
gl.drawBuffers([gl.COLOR_ATTACHMENT0]);
gl.drawBuffers(bufs);
gl.useProgram(redProgram);
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "there should be no errors");
wtu.drawUnitQuad(gl);
wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "Active draw buffers with missing frag outputs.");
gl.drawBuffers([gl.COLOR_ATTACHMENT0]);
wtu.drawUnitQuad(gl);
drawBuffersUtils.checkAttachmentsForColorFn(attachments, function(attachment, index) {

Просмотреть файл

@ -86,7 +86,6 @@ function testNonSquareFramebufferTextureWithChangingBaseLevel() {
{
var levelW = Math.floor(width / Math.pow(2, level));
var levelH = Math.floor(height / Math.pow(2, level));
gl.viewport(0, 0, levelW, levelH);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_BASE_LEVEL, level);
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, level);
@ -95,6 +94,7 @@ function testNonSquareFramebufferTextureWithChangingBaseLevel() {
gl.clearColor(0, 1, 0, 1);
gl.clear(gl.COLOR_BUFFER_BIT);
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Clearing the texture level " + level + " to green should succeed.");
wtu.checkCanvasRect(gl, 0, 0, 1, 1, [0, 255, 0, 255], "should be green");
++level;
}

Просмотреть файл

@ -108,7 +108,7 @@ if (!gl) {
function check_type_match() {
gl.useProgram(program0);
rendering([gl.COLOR_ATTACHMENT0, gl.NONE], gl.NO_ERROR);
rendering([gl.COLOR_ATTACHMENT0, gl.COLOR_ATTACHMENT1], gl.NO_ERROR);
rendering([gl.COLOR_ATTACHMENT0, gl.COLOR_ATTACHMENT1], gl.INVALID_OPERATION);
gl.useProgram(program1);
rendering([gl.COLOR_ATTACHMENT0, gl.NONE], gl.NO_ERROR);

Просмотреть файл

@ -1,148 +0,0 @@
<!--
/*
** 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">
<title>WebGL Rendering and Sampling Feedback Loop 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>
<canvas id="example" width="8" height="8"></canvas>
<div id="description"></div>
<div id="console"></div>
<script id="vshader" type="x-shader/x-vertex">#version 300 es
in highp vec4 aPosition;
in vec2 aTexCoord;
out vec2 texCoord;
void main() {
gl_Position = aPosition;
texCoord = aTexCoord;
}
</script>
<script id="fshader" type="x-shader/x-fragment">#version 300 es
precision mediump float;
uniform sampler2D tex;
in vec2 texCoord;
out vec4 oColor;
void main() {
oColor = texture(tex, texCoord);
}
</script>
<script>
"use strict";
var wtu = WebGLTestUtils;
description("This test verifies the functionality of rendering to the same texture where it samples from.");
var gl = wtu.create3DContext("example", undefined, 2);
var width = 8;
var height = 8;
var tex0;
var tex1;
var fbo;
var program;
var positionLoc;
var texCoordLoc;
if (!gl) {
testFailed("WebGL context does not exist");
} else {
testPassed("WebGL context exists");
init();
// The sampling texture is bound to COLOR_ATTACHMENT1 during resource allocation
allocate_resource();
rendering_sampling_feedback_loop([gl.NONE, gl.COLOR_ATTACHMENT1], gl.INVALID_OPERATION);
rendering_sampling_feedback_loop([gl.COLOR_ATTACHMENT0, gl.COLOR_ATTACHMENT1], gl.INVALID_OPERATION);
rendering_sampling_feedback_loop([gl.COLOR_ATTACHMENT0, gl.NONE], gl.NO_ERROR);
}
function init() {
program = wtu.setupProgram(gl, ['vshader', 'fshader'], ['aPosition', 'aTexCoord'], [0, 1]);
positionLoc = gl.getAttribLocation(program, "aPosition");
texCoordLoc = gl.getAttribLocation(program, "aTexCoord");
if (!program || positionLoc < 0 || texCoordLoc < 0) {
testFailed("Set up program failed");
return;
}
testPassed("Set up program succeeded");
wtu.setupUnitQuad(gl, 0, 1);
gl.viewport(0, 0, width, height);
}
function allocate_resource() {
tex0 = gl.createTexture();
tex1 = gl.createTexture();
fbo = gl.createFramebuffer();
wtu.fillTexture(gl, tex0, width, height, [0xff, 0x0, 0x0, 0xff], 0, gl.RGBA, gl.UNSIGNED_BYTE, gl.RGBA);
wtu.fillTexture(gl, tex1, width, height, [0x0, 0xff, 0x0, 0xff], 0, gl.RGBA, gl.UNSIGNED_BYTE, gl.RGBA);
gl.bindTexture(gl.TEXTURE_2D, tex1);
var texLoc = gl.getUniformLocation(program, "tex");
gl.uniform1i(texLoc, 0);
gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex0, 0);
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT1, gl.TEXTURE_2D, tex1, 0);
}
function rendering_sampling_feedback_loop(draw_buffers, error) {
gl.drawBuffers(draw_buffers);
// Make sure framebuffer is complete before feedback loop detection
if (gl.checkFramebufferStatus(gl.FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE) {
testFailed("Framebuffer incomplete.");
return;
}
wtu.clearAndDrawUnitQuad(gl);
wtu.glErrorShouldBe(gl, error, "Rendering to a texture where it samples from should geneates INVALID_OPERATION. Otherwise, it should be NO_ERROR");
}
gl.bindTexture(gl.TEXTURE_2D, null);
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
gl.deleteTexture(tex0);
gl.deleteTexture(tex1);
gl.deleteFramebuffer(fbo);
var successfullyParsed = true;
</script>
<script src="../../js/js-test-post.js"></script>
</body>
</html>

Просмотреть файл

@ -0,0 +1,240 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>WebGL 2 gl_VertexID Tests</title>
<link rel="stylesheet" href="../../resources/js-test-style.css"/>
<script src="../../js/desktop-gl-constants.js"></script>
<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>
<!-- Shaders for testing instanced draws -->
<script id="vs" type="text/plain">
#version 300 es
flat out highp int vVertexID;
void main() {
vVertexID = gl_VertexID;
gl_PointSize = 1.0;
gl_Position = vec4(0,0,0,1);
}
</script>
<script id="fs" type="text/plain">
#version 300 es
flat in highp int vVertexID;
out highp int oVertexID;
void main() {
oVertexID = vVertexID;
}
</script>
<script>
"use strict";
description("Test gl_VertexID");
debug("");
const wtu = WebGLTestUtils;
const canvas = document.createElement("canvas");
canvas.width = 1;
canvas.height = 1;
const gl = wtu.create3DContext(canvas, null, 2);
(function() {
if (!gl) {
testFailed("WebGL context does not exist");
return;
}
testPassed("WebGL context exists");
const vs = document.getElementById("vs").innerHTML.trim();
const fs = document.getElementById("fs").innerHTML.trim();
const prog = wtu.loadProgram(gl, vs, fs);
gl.useProgram(prog);
const tex = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, tex);
gl.texStorage2D(gl.TEXTURE_2D, 1, gl.R32I, 1, 1);
const fb = gl.createFramebuffer();
gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex, 0);
shouldBe("gl.checkFramebufferStatus(gl.FRAMEBUFFER)", "gl.FRAMEBUFFER_COMPLETE");
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "No errors after setup");
function shouldBeVal(prefix, expected, was) {
let text = prefix + "Should be " + expected;
let func = testPassed;
if (was != expected) {
text = text + ", was " + was;
func = testFailed;
}
func(text);
};
const readValData = new Int32Array(10000);
function ensureVal(prefix, expected) {
gl.readPixels(0, 0, 1, 1, gl.RGBA_INTEGER, gl.INT, readValData);
const was = readValData[0];
shouldBeVal(prefix, expected, was);
};
gl.clearBufferiv(gl.COLOR, 0, new Int32Array([42, 0, 0, 0]));
ensureVal("After clear", 42);
// -
debug("");
debug("----------------");
debug("drawArrays");
let test = function(first, count) {
debug("");
debug(`drawArrays(first: ${first}, count: ${count})`);
gl.drawArrays(gl.POINTS, first, count);
wtu.glErrorShouldBe(gl, gl.NO_ERROR);
ensureVal("", first+count-1);
};
test(0, 1);
test(1, 1);
test(10000, 1);
test(100000, 1);
test(1000000, 1);
test(0, 2);
test(1, 2);
test(10000, 2);
test(100000, 2);
test(1000000, 2);
const INT32_MAX = 0x7fffffff;
test = function(first, count) {
debug("");
debug(`drawArrays(first: ${first}, count: ${count})`);
gl.drawArrays(gl.POINTS, first, count);
if (!wtu.glErrorShouldBe(gl, [gl.NO_ERROR, gl.OUT_OF_MEMORY])) {
ensureVal("", first+count-1);
}
};
test(INT32_MAX-2, 1);
test(INT32_MAX-1, 1);
test(INT32_MAX, 1);
// -
debug("");
debug("----------------");
debug("drawElements");
const indexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);
const indexData = new Uint16Array([1, 2, 5, 3, 10000]);
debug("indexData: " + indexData);
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indexData, gl.STATIC_DRAW);
test = function(first, count) {
debug("");
debug(`drawElements(first: ${first}, count: ${count})`);
gl.drawElements(gl.POINTS, count, gl.UNSIGNED_SHORT, first*2);
wtu.glErrorShouldBe(gl, gl.NO_ERROR);
ensureVal("", indexData[first+count-1]);
};
for (let f = 0; f < indexData.length; ++f) {
for (let c = 1; f + c <= indexData.length; ++c) {
test(f, c);
}
}
// -
debug("");
debug("----------------");
debug("Via transform feedback");
gl.transformFeedbackVaryings(prog, ["vVertexID"], gl.INTERLEAVED_ATTRIBS);
wtu.linkProgram(gl, prog);
gl.useProgram(prog);
const tfBuffer = gl.createBuffer();
gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 0, tfBuffer);
gl.bufferData(gl.TRANSFORM_FEEDBACK_BUFFER, 4*10000, gl.DYNAMIC_READ);
test = function(offset, count) {
debug("");
debug("drawArrays(" + offset + ", " + count + ")");
gl.beginTransformFeedback(gl.POINTS);
gl.drawArrays(gl.POINTS, offset, count);
gl.endTransformFeedback();
gl.getBufferSubData(gl.TRANSFORM_FEEDBACK_BUFFER, 0, readValData);
let ok = true;
for (let i = 0; i < readValData.length; i++) {
if (i >= count)
break;
const expected = offset + i;
const was = readValData[i];
if (was != expected) {
testFailed("[" + i + "] expected " + expected + ", was " + was);
ok = false;
break;
}
}
if (ok) {
testPassed("ok");
}
};
test(0, 1);
test(1, 1);
test(10000, 1);
test(0, 2);
test(1, 2);
test(10000, 2);
test(10000, 10000);
// -
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "There should be no remaining errors");
})();
debug("");
var successfullyParsed = true;
</script>
<script src="../../js/js-test-post.js"></script>
</body>
</html>
<!--
/*
** Copyright (c) 2013 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.
*/
-->

Просмотреть файл

@ -8,6 +8,7 @@ copy-texture-image.html
copy-texture-image-luma-format.html
--min-version 2.0.1 copy-texture-image-same-texture.html
copy-texture-image-webgl-specific.html
--min-version 2.0.1 generate-mipmap-with-large-base-level.html
gl-get-tex-parameter.html
--min-version 2.0.1 integer-cubemap-texture-sampling.html
--min-version 2.0.1 integer-cubemap-specification-order-bug.html

Просмотреть файл

@ -70,7 +70,7 @@ function checkFramebuffer(expected) {
}
var testInternalformat = function () {
var goodByteFormats = [
var goodUnormFormats = [
"RGB",
"RGBA",
"LUMINANCE_ALPHA",
@ -81,7 +81,7 @@ var testInternalformat = function () {
"RGB8",
"RGBA8",
];
var goodByteFormatsWithUnmatchedComponentSizes = [
var goodUnormFormatsWithUnmatchedComponentSizes = [
"RGB565",
"RGBA4",
"RGB5_A1",
@ -94,6 +94,7 @@ var testInternalformat = function () {
var goodIntFormats = [
"R32I",
"RG32I",
"RGB32I",
"RGBA32I",
];
var goodIntFormatsWithUnmatchedComponentSizes = [
@ -101,12 +102,15 @@ var testInternalformat = function () {
"R16I",
"RG8I",
"RG16I",
"RGB8I",
"RGB16I",
"RGBA8I",
"RGBA16I",
];
var goodUnsignedIntFormats = [
"R32UI",
"RG32UI",
"RGB32UI",
"RGBA32UI",
];
var goodUnsignedIntFormatsWithUnmatchedComponentSizes = [
@ -115,26 +119,33 @@ var testInternalformat = function () {
"RG8UI",
"RG16UI",
"RGB10_A2UI",
"RGB8UI",
"RGB16UI",
"RGBA8UI",
"RGBA16UI",
];
var badByteFormats = [
const snormFormats = [
"R8_SNORM",
"RG8_SNORM",
"RGB8_SNORM",
"RGBA8_SNORM",
];
var badIntFormats = [
"RGB8I",
"RGB16I",
"RGB32I",
const float16Formats = [
"R16F",
"RG16F",
"RGB16F",
"RGBA16F",
];
var badUnsingedIntFormats = [
"RGB8UI",
"RGB16UI",
"RGB32UI",
const float32Formats = [
"R32F",
"RG32F",
"RGB32F",
"RGBA32F",
];
var badDepthStencilFormats = [
const float11Formats = [
"R11F_G11F_B10F",
];
const depthAndOrStencilFormats = [
"DEPTH_COMPONENT16",
"DEPTH_COMPONENT24",
"DEPTH_COMPONENT32F",
@ -148,68 +159,97 @@ var testInternalformat = function () {
var fbo = gl.createFramebuffer();
var srcTexture = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, srcTexture);
gl.texImage2D(gl.TEXTURE_2D, 0, srcTexFormatsTypes.internalformat, 64, 64, 0, srcTexFormatsTypes.format, srcTexFormatsTypes.type, null);
gl.texImage2D(gl.TEXTURE_2D, 0, gl[srcTexFormatsTypes.internalformat], 64, 64, 0, srcTexFormatsTypes.format, srcTexFormatsTypes.type, null);
gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
gl.framebufferTexture2D(gl.FRAMEBUFFER, fboAttachmentType, gl.TEXTURE_2D, srcTexture, 0);
checkFramebuffer([gl.FRAMEBUFFER_COMPLETE]);
gl.bindTexture(gl.TEXTURE_2D, texture);
gl.copyTexImage2D(gl.TEXTURE_2D, 0, gl[internalformat], 0, 0, 64, 64, 0);
wtu.glErrorShouldBe(gl, expected, msg + enumToString(gl[internalformat]));
wtu.glErrorShouldBe(gl, expected, msg + srcTexFormatsTypes.internalformat + '=>' + internalformat);
gl.deleteTexture(srcTexture);
gl.deleteFramebuffer(fbo);
}
goodByteFormats.forEach(function(internalformat) {
var srcTexFormatsTypes = { internalformat: gl.RGBA, format: gl.RGBA, type: gl.UNSIGNED_BYTE };
goodUnormFormats.forEach(function(internalformat) {
var srcTexFormatsTypes = { internalformat: "RGBA", format: gl.RGBA, type: gl.UNSIGNED_BYTE };
testFormat(internalformat, srcTexFormatsTypes, gl.COLOR_ATTACHMENT0, gl.NO_ERROR, "copyTexImage2D should succeed for good internalformat ");
srcTexFormatsTypes = { internalformat: gl.RGBA8, format: gl.RGBA, type: gl.UNSIGNED_BYTE };
srcTexFormatsTypes = { internalformat: "RGBA8", format: gl.RGBA, type: gl.UNSIGNED_BYTE };
testFormat(internalformat, srcTexFormatsTypes, gl.COLOR_ATTACHMENT0, gl.NO_ERROR, "copyTexImage2D should succeed for good internalformat ");
});
goodByteFormatsWithUnmatchedComponentSizes.forEach(function(internalformat) {
var srcTexFormatsTypes = { internalformat: gl.RGBA8, format: gl.RGBA, type: gl.UNSIGNED_BYTE };
goodUnormFormatsWithUnmatchedComponentSizes.forEach(function(internalformat) {
var srcTexFormatsTypes = { internalformat: "RGBA8", format: gl.RGBA, type: gl.UNSIGNED_BYTE };
testFormat(internalformat, srcTexFormatsTypes, gl.COLOR_ATTACHMENT0, gl.INVALID_OPERATION,
"copyTexImage2D should fail for good internalformat with unmatched component sizes ");
});
goodSRGBFormats.forEach(function(internalformat) {
var srcTexFormatsTypes = { internalformat: gl.SRGB8_ALPHA8, format: gl.RGBA, type: gl.UNSIGNED_BYTE };
var srcTexFormatsTypes = { internalformat: "SRGB8_ALPHA8", format: gl.RGBA, type: gl.UNSIGNED_BYTE };
testFormat(internalformat, srcTexFormatsTypes, gl.COLOR_ATTACHMENT0, gl.NO_ERROR, "copyTexImage2D should succeed for good internalformat ");
});
goodIntFormats.forEach(function(internalformat) {
var srcTexFormatsTypes = { internalformat: gl.RGBA32I, format: gl.RGBA_INTEGER, type: gl.INT };
var srcTexFormatsTypes = { internalformat: "RGBA32I", format: gl.RGBA_INTEGER, type: gl.INT };
testFormat(internalformat, srcTexFormatsTypes, gl.COLOR_ATTACHMENT0, gl.NO_ERROR, "copyTexImage2D should succeed for good internalformat ");
});
goodIntFormatsWithUnmatchedComponentSizes.forEach(function(internalformat) {
var srcTexFormatsTypes = { internalformat: gl.RGBA32I, format: gl.RGBA_INTEGER, type: gl.INT };
testFormat(internalformat, srcTexFormatsTypes, gl.COLOR_ATTACHMENT0, gl.INVALID_OPERATION,
"copyTexImage2D should fail for good internalformat with unmatched component sizes ");
});
goodUnsignedIntFormats.forEach(function(internalformat) {
var srcTexFormatsTypes = { internalformat: gl.RGBA32UI, format: gl.RGBA_INTEGER, type: gl.UNSIGNED_INT };
testFormat(internalformat, srcTexFormatsTypes, gl.COLOR_ATTACHMENT0, gl.NO_ERROR, "copyTexImage2D should succeed for good internalformat ");
});
goodUnsignedIntFormatsWithUnmatchedComponentSizes.forEach(function(internalformat) {
var srcTexFormatsTypes = { internalformat: gl.RGBA32UI, format: gl.RGBA_INTEGER, type: gl.UNSIGNED_INT };
var srcTexFormatsTypes = { internalformat: "RGBA32I", format: gl.RGBA_INTEGER, type: gl.INT };
testFormat(internalformat, srcTexFormatsTypes, gl.COLOR_ATTACHMENT0, gl.INVALID_OPERATION,
"copyTexImage2D should fail for good internalformat with unmatched component sizes ");
});
badByteFormats.forEach(function(internalformat) {
var srcTexFormatsTypes = { internalformat: gl.RGBA8, format: gl.RGBA, type: gl.UNSIGNED_BYTE };
testFormat(internalformat, srcTexFormatsTypes, gl.COLOR_ATTACHMENT0, gl.INVALID_ENUM, "copyTexImage2D should fail for bad internalformat ");
goodUnsignedIntFormats.forEach(function(internalformat) {
var srcTexFormatsTypes = { internalformat: "RGBA32UI", format: gl.RGBA_INTEGER, type: gl.UNSIGNED_INT };
testFormat(internalformat, srcTexFormatsTypes, gl.COLOR_ATTACHMENT0, gl.NO_ERROR, "copyTexImage2D should succeed for good internalformat ");
});
badIntFormats.forEach(function(internalformat) {
var srcTexFormatsTypes = { internalformat: gl.RGBA32I, format: gl.RGBA_INTEGER, type: gl.INT };
testFormat(internalformat, srcTexFormatsTypes, gl.COLOR_ATTACHMENT0, gl.INVALID_ENUM, "copyTexImage2D should fail for bad internalformat ");
goodUnsignedIntFormatsWithUnmatchedComponentSizes.forEach(function(internalformat) {
var srcTexFormatsTypes = { internalformat: "RGBA32UI", format: gl.RGBA_INTEGER, type: gl.UNSIGNED_INT };
testFormat(internalformat, srcTexFormatsTypes, gl.COLOR_ATTACHMENT0, gl.INVALID_OPERATION,
"copyTexImage2D should fail for good internalformat with unmatched component sizes ");
});
badUnsingedIntFormats.forEach(function(internalformat) {
var srcTexFormatsTypes = { internalformat: gl.RGBA32UI, format: gl.RGBA_INTEGER, type: gl.UNSIGNED_INT };
testFormat(internalformat, srcTexFormatsTypes, gl.COLOR_ATTACHMENT0, gl.INVALID_ENUM, "copyTexImage2D should fail for bad internalformat ");
snormFormats.forEach(function(internalformat) {
const srcTexFormatsTypes = { internalformat: "RGBA8", format: gl.RGBA, type: gl.UNSIGNED_BYTE };
testFormat(internalformat, srcTexFormatsTypes, gl.COLOR_ATTACHMENT0, gl.INVALID_ENUM, "copyTexImage2D should fail for snorm internalformat ");
});
badDepthStencilFormats.forEach(function(internalformat) {
var srcTexFormatsTypes = { internalformat: gl.DEPTH24_STENCIL8, format: gl.DEPTH_STENCIL, type: gl.UNSIGNED_INT_24_8};
testFormat(internalformat, srcTexFormatsTypes, gl.DEPTH_STENCIL_ATTACHMENT, gl.INVALID_ENUM, "copyTexImage2D should fail for bad internalformat ");
if (gl.getExtension("EXT_color_buffer_float")) {
float16Formats.forEach(function(internalformat) {
var srcTexFormatsTypes = { internalformat: "RGBA16F", format: gl.RGBA, type: gl.FLOAT };
testFormat(internalformat, srcTexFormatsTypes, gl.COLOR_ATTACHMENT0, gl.NO_ERROR, "copyTexImage2D should succeed for float16 internalformat ");
});
float32Formats.forEach(function(internalformat) {
var srcTexFormatsTypes = { internalformat: "RGBA32F", format: gl.RGBA, type: gl.FLOAT };
testFormat(internalformat, srcTexFormatsTypes, gl.COLOR_ATTACHMENT0, gl.NO_ERROR, "copyTexImage2D should succeed for float32 internalformat ");
});
float11Formats.forEach(function(internalformat) {
var srcTexFormatsTypes = { internalformat: "R11F_G11F_B10F", format: gl.RGB, type: gl.FLOAT };
testFormat(internalformat, srcTexFormatsTypes, gl.COLOR_ATTACHMENT0, gl.NO_ERROR, "copyTexImage2D should succeed for R11F_G11F_B10F internalformat ");
});
float32Formats.concat(float11Formats).forEach(function(internalformat) {
var srcTexFormatsTypes = { internalformat: "RGBA16F", format: gl.RGBA, type: gl.FLOAT };
testFormat(internalformat, srcTexFormatsTypes, gl.COLOR_ATTACHMENT0, gl.INVALID_OPERATION,
"copyTexImage2D should fail for non-float16 internalformat (unmatched component sizes) ");
});
float16Formats.concat(float11Formats).forEach(function(internalformat) {
var srcTexFormatsTypes = { internalformat: "RGBA32F", format: gl.RGBA, type: gl.FLOAT };
testFormat(internalformat, srcTexFormatsTypes, gl.COLOR_ATTACHMENT0, gl.INVALID_OPERATION,
"copyTexImage2D should fail for non-float32 internalformat (unmatched component sizes) ");
});
float16Formats.concat(float32Formats).forEach(function(internalformat) {
var srcTexFormatsTypes = { internalformat: "R11F_G11F_B10F", format: gl.RGB, type: gl.FLOAT };
testFormat(internalformat, srcTexFormatsTypes, gl.COLOR_ATTACHMENT0, gl.INVALID_OPERATION,
"copyTexImage2D should fail for non-R11F_G11F_B10F internalformat (unmatched component sizes) ");
});
}
depthAndOrStencilFormats.forEach(function(internalformat) {
var srcTexFormatsTypes = { internalformat: "DEPTH24_STENCIL8", format: gl.DEPTH_STENCIL, type: gl.UNSIGNED_INT_24_8};
testFormat(internalformat, srcTexFormatsTypes, gl.DEPTH_STENCIL_ATTACHMENT,
[gl.INVALID_ENUM, gl.INVALID_OPERATION],
"copyTexImage2D should fail for depth internalformat ");
});
gl.deleteTexture(texture);

Просмотреть файл

@ -0,0 +1,77 @@
<!--
/*
** Copyright (c) 2018 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>Test if GenerateMipmap on immutable texture with large BASE_LEVEL triggers a crash</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>
<canvas id="example" width="24" height="24"></canvas>
<div id="description"></div>
<div id="console"></div>
<script>
"use strict";
description("This is a regression test for crbug.com/913301");
debug("");
var wtu = WebGLTestUtils;
var gl = wtu.create3DContext("example", null, 2);
gl.clearColor(0, 1, 0, 1);
var targets = [gl.TEXTURE_2D, gl.TEXTURE_3D];
for (var ii = 0; ii < targets.length; ++ii) {
gl.clear(gl.COLOR_BUFFER_BIT);
var target = targets[ii];
var tex = gl.createTexture();
gl.bindTexture(target, tex);
gl.texParameteri(target, gl.TEXTURE_BASE_LEVEL, 1416354905);
gl.texParameteri(target, gl.TEXTURE_MAX_LEVEL, 5);
gl.texParameteri(target, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_LINEAR);
gl.texParameteri(target, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
if (target == gl.TEXTURE_2D)
gl.texStorage2D(target, 5, gl.R8, 32, 32);
else
gl.texStorage3D(target, 5, gl.R8, 32, 32, 32);
// Should not crash calling generateMipmap.
gl.generateMipmap(target);
gl.deleteTexture(tex);
// If crashed, readPixels() won't be able to work correctly.
wtu.checkCanvas(gl, [0, 255, 0, 255], "should be green", 5);
wtu.glErrorShouldBe(gl, gl.NO_ERROR);
}
var successfullyParsed = true;
</script>
<script src="../../../js/js-test-post.js"></script>
</body>
</html>

Просмотреть файл

@ -108,6 +108,10 @@ function createTextureCube(layers, maxLevel) {
return texture;
}
function makePermutedLayers(layers, permutation) {
return permutation.map(i => layers[i]);
}
function test() {
var kMaxLevel = 4;
var kBlack = 0x0000;
@ -151,9 +155,6 @@ function test() {
}
var regularTex = createTextureCube(regularLayers, kMaxLevel);
var weirdTex = createTextureCube(weirdLayers, kMaxLevel);
// At this point both textures should be the same.
var sampleProgram = wtu.setupProgram(gl, ["vs", "fs"], ["a_position"]);
var regularLocation = gl.getUniformLocation(sampleProgram, "texRegular");
@ -161,22 +162,68 @@ function test() {
wtu.setupQuad(gl, gl.getAttribLocation(sampleProgram, "a_position"));
gl.clearColor(0.0, 0.0, 0.0, 0.0);
gl.activeTexture(gl.TEXTURE0);
gl.bindTexture(gl.TEXTURE_CUBE_MAP, regularTex);
gl.activeTexture(gl.TEXTURE0 + 1);
gl.bindTexture(gl.TEXTURE_CUBE_MAP, weirdTex);
gl.uniform1i(regularLocation, 0);
gl.uniform1i(weirdLocation, 1);
wtu.drawUnitQuad(gl);
function testcase(layers1, casename) {
var tex1 = createTextureCube(layers1, kMaxLevel);
wtu.checkCanvasRect(gl, 96, 32, 1, 1, [255, 0, 0, 255], "should be green");
wtu.checkCanvasRect(gl, 96, 96, 1, 1, [255, 0, 0, 255], "should be green");
wtu.checkCanvasRect(gl, 32, 32, 1, 1, [0, 255, 0, 255], "should be red");
wtu.checkCanvasRect(gl, 32, 96, 1, 1, [0, 255, 0, 255], "should be red");
gl.activeTexture(gl.TEXTURE0);
gl.bindTexture(gl.TEXTURE_CUBE_MAP, regularTex);
gl.activeTexture(gl.TEXTURE1);
gl.bindTexture(gl.TEXTURE_CUBE_MAP, tex1);
// At this point both textures should be the same.
wtu.drawUnitQuad(gl);
gl.deleteTexture(tex1);
wtu.checkCanvasRect(gl, 96, 32, 1, 1, [255, 0, 0, 255], "should be green: " + casename);
wtu.checkCanvasRect(gl, 96, 96, 1, 1, [255, 0, 0, 255], "should be green: " + casename);
wtu.checkCanvasRect(gl, 32, 32, 1, 1, [0, 255, 0, 255], "should be red: " + casename);
wtu.checkCanvasRect(gl, 32, 96, 1, 1, [0, 255, 0, 255], "should be red: " + casename);
}
testcase(weirdLayers, "original");
const cases = [
[10,23,3,19,26,29,14,9,4,11,27,28,13,24,20,12,17,21,16,5,6,25,1,15,22,8,7,18,0,2],
[10,27,3,29,17,28,13,20,18,25,9,2,8,4,24,12,15,7,19,11,6,14,16,21,1,26,23,22,0,5],
[11,4,15,13,26,24,25,2,19,20,16,23,1,18,28,27,6,21,14,8,17,29,3,10,12,9,22,7,0,5],
[14,2,6,28,7,25,11,26,22,13,19,21,24,4,16,29,9,27,3,17,18,15,12,20,8,23,10,1,0,5],
[14,20,22,16,11,27,17,21,15,3,5,28,6,2,9,12,7,24,1,26,8,19,23,25,18,13,29,10,0,4],
[14,20,22,16,11,27,17,21,15,3,5,28,6,2,9,12,7,24,1,26,8,19,23,25,18,13,29,10,0,4],
[14,22,27,1,12,24,13,21,6,10,20,28,23,16,5,18,7,3,25,2,11,19,17,26,8,29,15,9,0,4],
[15,22,13,28,6,12,19,9,18,11,3,23,17,8,10,20,5,14,4,25,27,26,21,16,29,24,7,0,1,2],
[15,22,13,28,6,12,19,9,18,11,3,23,17,8,10,20,5,14,4,25,27,26,21,16,29,24,7,0,1,2],
[16,22,18,15,19,6,21,27,4,14,29,17,7,9,11,20,24,23,28,25,2,13,10,26,8,12,3,0,5,1],
[16,26,18,7,20,25,11,24,2,1,28,13,29,10,27,21,6,15,5,19,17,12,14,9,23,22,8,3,0,4],
[2,22,25,12,19,16,7,27,9,10,8,17,18,24,1,21,20,14,13,4,11,29,15,5,23,26,6,28,0,3],
[2,9,16,26,6,15,4,3,17,13,21,10,7,22,23,29,19,18,12,24,14,25,8,5,20,28,11,27,0,1],
[2,9,16,26,6,15,4,3,17,13,21,10,7,22,23,29,19,18,12,24,14,25,8,5,20,28,11,27,0,1],
[20,21,24,15,5,13,6,12,2,17,10,14,27,16,8,22,9,25,29,1,28,11,4,19,7,23,26,18,0,3],
[21,14,19,12,28,6,10,7,16,27,11,22,20,24,25,26,3,8,4,18,5,2,9,15,17,23,13,29,0,1],
[22,4,18,7,11,6,23,17,14,3,13,21,15,19,25,28,9,8,10,12,29,16,27,2,24,1,20,26,0,5],
[22,4,18,7,11,6,23,17,14,3,13,21,15,19,25,28,9,8,10,12,29,16,27,2,24,1,20,26,0,5],
[23,21,9,28,22,15,25,12,24,18,29,2,17,1,14,4,16,26,3,11,27,13,8,7,6,20,10,19,0,5],
[23,6,15,13,19,2,12,7,11,29,3,20,17,10,4,18,1,22,16,27,24,9,21,25,14,26,8,28,0,5],
[25,12,1,4,9,22,16,28,6,11,14,29,15,2,5,13,10,20,21,19,23,27,18,26,7,8,17,24,0,3],
[25,13,29,26,28,17,19,23,7,24,10,1,15,8,3,11,18,21,27,22,12,5,9,6,16,14,20,2,0,4],
[25,18,28,12,27,13,11,4,29,8,21,15,9,6,26,20,22,23,24,17,5,16,2,7,14,19,10,0,1,3],
[25,19,3,10,23,15,27,18,12,8,7,24,16,14,26,4,21,5,9,1,22,28,20,29,6,11,13,17,0,2],
[25,24,12,9,13,10,23,4,19,29,16,1,15,8,21,26,18,11,17,7,20,28,22,14,27,6,0,2,5,3],
[25,9,29,8,3,6,10,27,11,28,13,23,18,16,17,19,5,22,12,26,21,4,7,14,24,15,2,20,0,1],
[27,23,20,2,12,14,6,19,3,28,18,10,29,11,13,22,21,7,15,9,8,17,25,16,26,24,4,5,0,1],
[27,7,2,5,19,10,3,26,22,18,23,16,9,24,21,17,6,28,12,14,25,29,13,15,8,20,11,4,0,1],
[28,7,10,9,29,27,2,20,1,26,11,5,12,23,25,3,17,16,24,13,8,6,14,18,21,19,15,22,0,4],
[28,8,23,13,18,29,20,9,10,27,15,21,3,19,14,4,26,5,24,1,6,17,11,12,16,7,25,22,0,2],
[29,12,13,2,22,19,16,7,14,11,24,23,28,15,17,9,20,21,18,26,27,25,10,5,8,6,4,3,0,1],
[29,8,5,4,7,15,19,17,3,26,13,9,23,6,25,22,27,24,14,16,10,21,11,18,28,12,2,20,0,1],
[5,18,6,17,19,16,13,11,28,8,10,4,29,26,20,24,9,7,21,25,27,23,22,2,15,14,12,0,3,1],
[5,23,2,15,7,13,19,11,27,3,22,14,4,26,28,20,17,18,8,25,16,29,10,24,12,9,6,21,0,1],
[7,24,27,26,16,18,22,20,10,11,9,19,23,12,17,13,4,2,6,1,21,25,15,28,8,3,29,14,0,5],
];
for (const c of cases) {
testcase(makePermutedLayers(regularLayers, c), "case " + c.toString());
}
}
test();

Просмотреть файл

@ -134,6 +134,7 @@ function runNextVideo() {
debug("");
debug("testing: " + videoInfo.type);
video = document.createElement("video");
video.muted = true;
var canPlay = true;
if (!video.canPlayType) {
testFailed("video.canPlayType required method missing");

Просмотреть файл

@ -123,13 +123,13 @@ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors from setup.");
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "texParameter(TEXTURE_MIN_FILTER) should succeed");
wtu.clearAndDrawUnitQuad(gl);
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "clearAndDrawQuad should succeed");
wtu.checkCanvas(gl, [0, 0, 255, 255], "should draw with [0, 0, 255, 255]");
wtu.checkCanvas(gl, [0, 0, 255, 255], "filling partial levels: should draw with [0, 0, 255, 255]");
// Test that generateMipmap works with partial levels.
gl.generateMipmap(gl.TEXTURE_2D);
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "generateMipmap should succeed");
wtu.clearAndDrawUnitQuad(gl);
wtu.checkCanvas(gl, [255, 0, 0, 255], "should draw with [255, 0, 0, 255]");
wtu.checkCanvas(gl, [255, 0, 0, 255], "generateMipmap with partial levels: should draw with [255, 0, 0, 255]");
gl.deleteTexture(tex);
// Test incompleteless for partial levels.
@ -190,9 +190,8 @@ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors from setup.");
tex = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, tex);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA8, 0, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
// https://github.com/KhronosGroup/WebGL/pull/2728
//gl.generateMipmap(gl.TEXTURE_2D);
//wtu.glErrorShouldBe(gl, gl.NO_ERROR, "generateMipmap should succeed for zero-size texture");
gl.generateMipmap(gl.TEXTURE_2D);
wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "generateMipmap should fail for zero-size texture");
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA8, 8, 8, 0, gl.RGBA, gl.UNSIGNED_BYTE, new Uint8Array(8 * 8 * 4));
gl.generateMipmap(gl.TEXTURE_2D);
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "generateMipmap should succeed");
@ -206,9 +205,8 @@ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors from setup.");
}
if (gl.getExtension('EXT_color_buffer_float') && gl.getExtension('OES_texture_float_linear')) {
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA32F, 0, 0, 0, gl.RGBA, gl.FLOAT, null);
// https://github.com/KhronosGroup/WebGL/pull/2728
//gl.generateMipmap(gl.TEXTURE_2D);
//wtu.glErrorShouldBe(gl, gl.NO_ERROR, "generateMipmap should succeed for zero-size texture");
gl.generateMipmap(gl.TEXTURE_2D);
wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "generateMipmap should fail for zero-size texture");
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA32F, 8, 8, 0, gl.RGBA, gl.FLOAT, new Float32Array(8 * 8 * 4));
gl.generateMipmap(gl.TEXTURE_2D);
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "generateMipmap should succeed");
@ -234,7 +232,7 @@ wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors from setup.");
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "texStorage2D should succeed");
wtu.clearAndDrawUnitQuad(gl);
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "clearAndDrawQuad should succeed");
wtu.checkCanvas(gl, [255, 0, 0, 255], "should draw with [255, 0, 0, 255]");
wtu.checkCanvas(gl, [255, 0, 0, 255], "non-zero base level texStorage2D: should draw with [255, 0, 0, 255]");
gl.deleteTexture(tex);
})();

Просмотреть файл

@ -40,22 +40,103 @@
<script>
var wtu = WebGLTestUtils;
var gl = wtu.create3DContext(undefined, undefined, 2);
let actual;
description("TexImage3D from ImageData with unpack params");
debug("TexImage3D from ImageData with UNPACK_IMAGE_HEIGHT set (crbug.com/804123)");
let imageData = new ImageData(64, 64);
let texture = gl.createTexture();
// framebuffer for readback
const fbo = gl.createFramebuffer();
gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
function makeTestData(size, start) {
const data = new Uint8ClampedArray(size);
for (let i = 0; i < size; ++i) {
data[i] = (start + i) % 256;
}
return data;
}
// source data
//
// dstWidth = 4
// <-->
// xxxx ^ ^ ^ ^
// xxxx | | |
// xxxx | | |
// xxxx | | v dstHeight = 4
// ---- | |
// ---- | |
// ---- | v unpackImageHeight = 7
// xxxx | |
// xxxx |
// xxxx |
// xxxx |
// ---- |
// ---- |
// ---- |
// xxxx | |
// xxxx |
// xxxx |
// xxxx |
// ---- |
// ---- |
// ---- |
// xxxx | v dstDepth = 4
// xxxx |
// xxxx |
// xxxx v srcHeight = 25
// <-->
// srcWidth = 4
const unpackImageHeight = 7;
const dstWidth = 4;
const dstHeight = 4;
const dstDepth = 4;
const srcWidth = dstWidth;
const srcHeight = (dstDepth - 1) * unpackImageHeight + dstHeight;
const srcSize = srcWidth * srcHeight;
const sizeofR8 = 1;
const sizeofRGBA8 = 4;
const imageData = new ImageData(makeTestData(srcSize * sizeofRGBA8, 1), srcWidth, srcHeight);
const texture = gl.createTexture();
gl.bindTexture(gl.TEXTURE_3D, texture);
debug("");
// upload
gl.pixelStorei(gl.UNPACK_IMAGE_HEIGHT, 2);
gl.texImage3D(gl.TEXTURE_3D, 0, gl.R8, 1, 1, 1, 0, gl.RED, gl.UNSIGNED_BYTE, imageData);
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "small upload");
// check
actual = new Uint8Array(sizeofRGBA8);
gl.framebufferTextureLayer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, texture, 0, 0);
if (gl.checkFramebufferStatus(gl.FRAMEBUFFER) == gl.FRAMEBUFFER_COMPLETE) {
gl.readPixels(0, 0, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, actual);
shouldBeTrue(`areArraysEqual(actual, [1, 0, 0, 255])`);
wtu.glErrorShouldBe(gl, gl.NO_ERROR);
} else {
debug("framebuffer incomplete: skipped");
}
gl.pixelStorei(gl.UNPACK_IMAGE_HEIGHT, 7);
gl.texImage3D(gl.TEXTURE_3D, 0, gl.RGBA8, 4, 4, 4, 0, gl.RGBA, gl.UNSIGNED_BYTE, imageData);
debug("");
// upload
gl.pixelStorei(gl.UNPACK_IMAGE_HEIGHT, unpackImageHeight);
gl.texImage3D(gl.TEXTURE_3D, 0, gl.RGBA8, dstWidth, dstHeight, dstDepth, 0,
gl.RGBA, gl.UNSIGNED_BYTE, imageData);
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "larger upload");
// check
actual = new Uint8Array(dstWidth * dstHeight * sizeofRGBA8);
let expected;
for (let z = 0; z < dstDepth; ++z) {
gl.framebufferTextureLayer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, texture, 0, z);
shouldBe('gl.checkFramebufferStatus(gl.FRAMEBUFFER)', 'gl.FRAMEBUFFER_COMPLETE');
gl.readPixels(0, 0, dstWidth, dstHeight, gl.RGBA, gl.UNSIGNED_BYTE, actual);
debug(`for z = ${z}:`);
expected = makeTestData(dstWidth * dstHeight * sizeofRGBA8,
1 + z * dstWidth * unpackImageHeight * sizeofRGBA8);
shouldBeTrue('areArraysEqual(actual, expected)');
}
wtu.glErrorShouldBe(gl, gl.NO_ERROR);
gl.deleteTexture(texture);

Просмотреть файл

@ -1,8 +1,9 @@
--min-version 2.0.1 non-existent-varying.html
--min-version 2.0.1 default_transform_feedback.html
transform_feedback.html
two-unreferenced-varyings.html
--min-version 2.0.1 too-small-buffers.html
unwritten-output-defaults-to-zero.html
--min-version 2.0.1 same-buffer-two-binding-points.html
--min-version 2.0.1 simultaneous_binding.html
--min-version 2.0.1 switching-objects.html
--min-version 2.0.1 switching-objects.html

Просмотреть файл

@ -0,0 +1,136 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>WebGL Transform Feedback Conformance Test - Default Transform Feedback</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 id="vshader" type="x-shader/x-vertex">#version 300 es
in float in_value;
out float out_value;
void main() {
out_value = in_value * 2.;
}
</script>
<script id="fshader" type="x-shader/x-fragment">#version 300 es
precision mediump float;
out vec4 dummy;
void main() {
dummy = vec4(1);
}
</script>
<script>
"use strict";
description("This test verifies using the default transform feedback object");
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");
runDefaultTransformFeedbackTest();
finishTest();
}
function runDefaultTransformFeedbackTest() {
const prog = wtu.setupTransformFeedbackProgram(gl, ["vshader", "fshader"],
["out_value"], gl.SEPARATE_ATTRIBS,
["in_value"]);
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "linking transform feedback shader should not set an error");
const inLoc = 0;
const outLoc = 0;
const srcBuffer1 = createBuffer(gl, new Float32Array([1, 2, 3]));
const srcVAO1 = createVAO(gl, srcBuffer1, inLoc);
const dstBuffer = createBuffer(gl, Float32Array.BYTES_PER_ELEMENT * 3);
const tf = null; // use the default transform feedback gl.createTransformFeedback();
gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, tf);
gl.useProgram(prog);
gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, outLoc, dstBuffer);
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "there should be no errors binding a buffer to the default transform feedback");
runFeedback(gl, prog, srcVAO1, tf);
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "there should be no errors having drawn with the default transform feedback");
const expected = [2, 4, 6];
gl.bindBuffer(gl.TRANSFORM_FEEDBACK_BUFFER, dstBuffer);
wtu.checkFloatBuffer(gl, gl.TRANSFORM_FEEDBACK_BUFFER, expected);
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "there should be no errors after readback");
}
function runFeedback(gl, prog, srcVAO, tf, dstBufferInfo) {
gl.enable(gl.RASTERIZER_DISCARD);
gl.useProgram(prog);
gl.bindVertexArray(srcVAO);
gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, tf);
gl.beginTransformFeedback(gl.TRIANGLES);
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "there should be no errors setting up to draw with the default transform feedback");
gl.drawArrays(gl.TRIANGLES, 0, 3);
gl.endTransformFeedback();
gl.disable(gl.RASTERIZER_DISCARD);
}
function createBuffer(gl, dataOrSize) {
const buf = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, buf);
gl.bufferData(gl.ARRAY_BUFFER, dataOrSize, gl.STATIC_DRAW);
gl.bindBuffer(gl.ARRAY_BUFFER, null); // Clear this or we'll have tfo/non-tfo simultaneous usage.
return buf;
}
function createVAO(gl, buf, inLoc) {
const vao = gl.createVertexArray();
gl.bindVertexArray(vao);
gl.bindBuffer(gl.ARRAY_BUFFER, buf);
gl.enableVertexAttribArray(inLoc);
gl.vertexAttribPointer(inLoc, 1, gl.FLOAT, false, 0, 0);
gl.bindVertexArray(null);
return vao;
}
</script>
</body>
</html>
<!--
/*
** Copyright (c) 2019 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.
*/
-->

Просмотреть файл

@ -67,6 +67,7 @@ var gl = wtu.create3DContext(canvas, null, 2);
var tf = null;
var tf1 = null;
var buf = null;
let out_add_buffer = null;
var program = null;
var activeInfo = null;
var query = null;
@ -81,8 +82,11 @@ if (!gl) {
runTFBufferBindingTest();
runObjectTest();
runGetBufferSubDataTest();
runOneOutFeedbackTest();
runTwoOutFeedbackTest();
runUnboundDeleteTest();
runBoundDeleteTest();
runOneOutputFeedbackTest();
// Must be the last test, since it's asynchronous and calls finishTest().
runTwoOutputFeedbackTest();
}
function runBindingTest() {
@ -169,9 +173,9 @@ function runObjectTest() {
tf = null;
}
function runOneOutFeedbackTest() {
function runOneOutputFeedbackTest() {
debug("");
debug("Testing transform feedback processing");
debug("Testing one-output transform feedback");
// Build the input and output buffers
var in_data = [
@ -184,7 +188,7 @@ function runOneOutFeedbackTest() {
gl.bindBuffer(gl.ARRAY_BUFFER, in_buffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(in_data), gl.STATIC_DRAW);
var out_add_buffer = gl.createBuffer();
out_add_buffer = gl.createBuffer();
gl.bindBuffer(gl.TRANSFORM_FEEDBACK_BUFFER, out_add_buffer);
gl.bufferData(gl.TRANSFORM_FEEDBACK_BUFFER, Float32Array.BYTES_PER_ELEMENT * in_data.length, gl.STATIC_DRAW);
@ -208,6 +212,13 @@ function runOneOutFeedbackTest() {
gl.enable(gl.RASTERIZER_DISCARD);
gl.beginTransformFeedback(gl.POINTS);
debug("Testing deleting an active transform feedback object");
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no errors before testing deletion");
gl.deleteTransformFeedback(tf);
wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "Deleting the transform feedback while active should fail, and have no effect");
shouldBe("gl.isTransformFeedback(tf)", "true");
debug("Resuming testing of single-output transform feedback");
gl.drawArrays(gl.POINTS, 0, 3);
gl.endTransformFeedback();
@ -224,13 +235,18 @@ function runOneOutFeedbackTest() {
gl.bindBuffer(gl.TRANSFORM_FEEDBACK_BUFFER, out_add_buffer);
wtu.checkFloatBuffer(gl, gl.TRANSFORM_FEEDBACK_BUFFER, add_expected);
gl.deleteBuffer(in_buffer);
gl.deleteBuffer(out_add_buffer);
gl.deleteProgram(program);
gl.deleteTransformFeedback(tf);
tf = null;
program = null;
}
function runTwoOutFeedbackTest() {
function runTwoOutputFeedbackTest() {
debug("");
debug("Testing transform feedback processing");
debug("Testing two-output transform feedback");
// Build the input and output buffers
var in_data = [
@ -243,7 +259,7 @@ function runTwoOutFeedbackTest() {
gl.bindBuffer(gl.ARRAY_BUFFER, in_buffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(in_data), gl.STATIC_DRAW);
var out_add_buffer = gl.createBuffer();
out_add_buffer = gl.createBuffer();
gl.bindBuffer(gl.TRANSFORM_FEEDBACK_BUFFER, out_add_buffer);
gl.bufferData(gl.TRANSFORM_FEEDBACK_BUFFER, Float32Array.BYTES_PER_ELEMENT * in_data.length, gl.STATIC_DRAW);
@ -302,6 +318,12 @@ function runTwoOutFeedbackTest() {
gl.bindBuffer(gl.TRANSFORM_FEEDBACK_BUFFER, out_mul_buffer);
wtu.checkFloatBuffer(gl, gl.TRANSFORM_FEEDBACK_BUFFER, mul_expected);
gl.deleteBuffer(in_buffer);
gl.deleteBuffer(out_add_buffer);
gl.deleteBuffer(out_mul_buffer);
gl.deleteProgram(program);
gl.deleteTransformFeedback(tf);
tf = null;
program = null;
@ -324,6 +346,87 @@ function runTwoOutFeedbackTest() {
requestAnimationFrame(completeTransformFeedbackQueryTest);
}
function runUnboundDeleteTest() {
debug("");
debug("Testing deleting buffers attached to an unbound transform feedback object");
// Theoretically it would be possible to verify the result of performing
// transform feedback into a deleted buffer object. The buffer would have to
// be latched into a VAO as well as into the transform feedback object. In
// order to get the results out of the output buffer, it would be necessary
// to run transform feedback again, reading from the buffer bound to the
// VAO, and writing into a (non-deleted) buffer object latched into the
// transform feedback object. It's not possible to arrange things to be able
// to copyBufferSubData from the deleted buffer object into a temporary one
// for readback.
// This would be a lot of code to test an unlikely corner case, so instead,
// this test verifies simpler behaviors.
out_add_buffer = gl.createBuffer();
const output_buffer_length = Float32Array.BYTES_PER_ELEMENT * 16;
gl.bindBuffer(gl.TRANSFORM_FEEDBACK_BUFFER, out_add_buffer);
gl.bufferData(gl.TRANSFORM_FEEDBACK_BUFFER, output_buffer_length, gl.STATIC_DRAW);
// Set up the transform feedback object
tf = gl.createTransformFeedback();
gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, tf);
gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 0, out_add_buffer);
// Unbind transform feedback and delete out_add_buffer.
gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, null);
gl.deleteBuffer(out_add_buffer);
debug("isBuffer should report false after deletion");
shouldBe("gl.isBuffer(out_add_buffer)", "false");
gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, tf);
debug("Transform feedback object should keep output buffer alive");
shouldBe("gl.getIndexedParameter(gl.TRANSFORM_FEEDBACK_BUFFER_BINDING, 0)", "out_add_buffer");
// Deleting the buffer again while the transform feedback is bound shouldn't unbind it.
gl.deleteBuffer(out_add_buffer);
debug("Deleting output buffer again should be a no-op");
shouldBe("gl.getIndexedParameter(gl.TRANSFORM_FEEDBACK_BUFFER_BINDING, 0)", "out_add_buffer");
// Try unbinding and rebinding the transform feedback object just
// to make sure that has no effect on the attached output buffer.
gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, null);
gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, tf);
debug("Transform feedback object should still keep output buffer alive");
shouldBe("gl.getIndexedParameter(gl.TRANSFORM_FEEDBACK_BUFFER_BINDING, 0)", "out_add_buffer");
gl.deleteTransformFeedback(tf);
tf = null;
out_add_buffer = null;
}
function runBoundDeleteTest() {
debug("");
debug("Testing deleting buffers attached to a bound transform feedback object");
out_add_buffer = gl.createBuffer();
const output_buffer_length = Float32Array.BYTES_PER_ELEMENT * 16;
gl.bindBuffer(gl.TRANSFORM_FEEDBACK_BUFFER, out_add_buffer);
gl.bufferData(gl.TRANSFORM_FEEDBACK_BUFFER, output_buffer_length, gl.STATIC_DRAW);
// Set up the transform feedback object
tf = gl.createTransformFeedback();
gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, tf);
gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 0, out_add_buffer);
// Delete the output buffer
gl.deleteBuffer(out_add_buffer);
gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, tf);
debug("Buffer should have been unbound from active transform feedback");
shouldBeNull("gl.getIndexedParameter(gl.TRANSFORM_FEEDBACK_BUFFER_BINDING, 0)");
gl.deleteTransformFeedback(tf);
tf = null;
out_add_buffer = null;
}
var retArray;
function verifyGetBufferSubData(expected) {
@ -347,7 +450,7 @@ function runGetBufferSubDataTest() {
gl.bindBuffer(gl.ARRAY_BUFFER, in_buffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(in_data), gl.STATIC_DRAW);
var out_add_buffer = gl.createBuffer();
out_add_buffer = gl.createBuffer();
gl.bindBuffer(gl.TRANSFORM_FEEDBACK_BUFFER, out_add_buffer);
gl.bufferData(gl.TRANSFORM_FEEDBACK_BUFFER, Float32Array.BYTES_PER_ELEMENT * in_data.length, gl.STATIC_DRAW);
@ -448,8 +551,8 @@ function runVaryingsTest() {
debug("");
debug("Testing transform feedback varyings");
// Create the transform feedback shader. This is explicitly run after runFeedbackTest,
// as re-llinking the shader here will test browser caching.
// Create the transform feedback shader. This is explicitly run after runTwoOutputFeedbackTest,
// as re-linking the shader here will test browser caching.
program = wtu.setupTransformFeedbackProgram(gl, ["vshader", "fshader"],
["out_add", "out_mul"], gl.SEPARATE_ATTRIBS,
["in_data"]);

Просмотреть файл

@ -65,73 +65,84 @@ function makeFragmentShader(samplerType, uvType) {
`;
}
// Sampler types.
const FLOAT = 1;
const SIGNED = 2;
const UNSIGNED = 3;
const SHADOW = 4;
const textureInternalFormatInfo = {};
{
const t = textureInternalFormatInfo;
// unsized formats
t[gl.ALPHA] = { textureFormat: gl.ALPHA, colorRenderable: true, textureFilterable: true, bytesPerElement: [1, 2, 2, 4], type: [gl.UNSIGNED_BYTE, gl.HALF_FLOAT, gl.HALF_FLOAT_OES, gl.FLOAT], };
t[gl.LUMINANCE] = { textureFormat: gl.LUMINANCE, colorRenderable: true, textureFilterable: true, bytesPerElement: [1, 2, 2, 4], type: [gl.UNSIGNED_BYTE, gl.HALF_FLOAT, gl.HALF_FLOAT_OES, gl.FLOAT], };
t[gl.LUMINANCE_ALPHA] = { textureFormat: gl.LUMINANCE_ALPHA, colorRenderable: true, textureFilterable: true, bytesPerElement: [2, 4, 4, 8], type: [gl.UNSIGNED_BYTE, gl.HALF_FLOAT, gl.HALF_FLOAT_OES, gl.FLOAT], };
t[gl.RGB] = { textureFormat: gl.RGB, colorRenderable: true, textureFilterable: true, bytesPerElement: [3, 6, 6, 12, 2], type: [gl.UNSIGNED_BYTE, gl.HALF_FLOAT, gl.HALF_FLOAT_OES, gl.FLOAT, gl.UNSIGNED_SHORT_5_6_5], };
t[gl.RGBA] = { textureFormat: gl.RGBA, colorRenderable: true, textureFilterable: true, bytesPerElement: [4, 8, 8, 16, 2, 2], type: [gl.UNSIGNED_BYTE, gl.HALF_FLOAT, gl.HALF_FLOAT_OES, gl.FLOAT, gl.UNSIGNED_SHORT_4_4_4_4, gl.UNSIGNED_SHORT_5_5_5_1], };
t[gl.ALPHA] = { textureFormat: gl.ALPHA, samplerType: FLOAT, depth: false, bytesPerElement: [1, 2, 2, 4], type: [gl.UNSIGNED_BYTE, gl.HALF_FLOAT, gl.HALF_FLOAT_OES, gl.FLOAT], };
t[gl.LUMINANCE] = { textureFormat: gl.LUMINANCE, samplerType: FLOAT, depth: false, bytesPerElement: [1, 2, 2, 4], type: [gl.UNSIGNED_BYTE, gl.HALF_FLOAT, gl.HALF_FLOAT_OES, gl.FLOAT], };
t[gl.LUMINANCE_ALPHA] = { textureFormat: gl.LUMINANCE_ALPHA, samplerType: FLOAT, depth: false, bytesPerElement: [2, 4, 4, 8], type: [gl.UNSIGNED_BYTE, gl.HALF_FLOAT, gl.HALF_FLOAT_OES, gl.FLOAT], };
t[gl.RGB] = { textureFormat: gl.RGB, samplerType: FLOAT, depth: false, bytesPerElement: [3, 6, 6, 12, 2], type: [gl.UNSIGNED_BYTE, gl.HALF_FLOAT, gl.HALF_FLOAT_OES, gl.FLOAT, gl.UNSIGNED_SHORT_5_6_5], };
t[gl.RGBA] = { textureFormat: gl.RGBA, samplerType: FLOAT, depth: false, bytesPerElement: [4, 8, 8, 16, 2, 2], type: [gl.UNSIGNED_BYTE, gl.HALF_FLOAT, gl.HALF_FLOAT_OES, gl.FLOAT, gl.UNSIGNED_SHORT_4_4_4_4, gl.UNSIGNED_SHORT_5_5_5_1], };
// sized formats
t[gl.R8] = { textureFormat: gl.RED, colorRenderable: true, textureFilterable: true, bytesPerElement: [1], type: [gl.UNSIGNED_BYTE], };
t[gl.R8_SNORM] = { textureFormat: gl.RED, colorRenderable: false, textureFilterable: true, bytesPerElement: [1], type: [gl.BYTE], };
t[gl.R16F] = { textureFormat: gl.RED, colorRenderable: false, textureFilterable: true, bytesPerElement: [4, 2], type: [gl.FLOAT, gl.HALF_FLOAT], };
t[gl.R32F] = { textureFormat: gl.RED, colorRenderable: false, textureFilterable: false, bytesPerElement: [4], type: [gl.FLOAT], };
t[gl.R8UI] = { textureFormat: gl.RED_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [1], type: [gl.UNSIGNED_BYTE], };
t[gl.R8I] = { textureFormat: gl.RED_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [1], type: [gl.BYTE], };
t[gl.R16UI] = { textureFormat: gl.RED_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [2], type: [gl.UNSIGNED_SHORT], };
t[gl.R16I] = { textureFormat: gl.RED_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [2], type: [gl.SHORT], };
t[gl.R32UI] = { textureFormat: gl.RED_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [4], type: [gl.UNSIGNED_INT], };
t[gl.R32I] = { textureFormat: gl.RED_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [4], type: [gl.INT], };
t[gl.RG8] = { textureFormat: gl.RG, colorRenderable: true, textureFilterable: true, bytesPerElement: [2], type: [gl.UNSIGNED_BYTE], };
t[gl.RG8_SNORM] = { textureFormat: gl.RG, colorRenderable: false, textureFilterable: true, bytesPerElement: [2], type: [gl.BYTE], };
t[gl.RG16F] = { textureFormat: gl.RG, colorRenderable: false, textureFilterable: true, bytesPerElement: [8, 4], type: [gl.FLOAT, gl.HALF_FLOAT], };
t[gl.RG32F] = { textureFormat: gl.RG, colorRenderable: false, textureFilterable: false, bytesPerElement: [8], type: [gl.FLOAT], };
t[gl.RG8UI] = { textureFormat: gl.RG_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [2], type: [gl.UNSIGNED_BYTE], };
t[gl.RG8I] = { textureFormat: gl.RG_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [2], type: [gl.BYTE], };
t[gl.RG16UI] = { textureFormat: gl.RG_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [4], type: [gl.UNSIGNED_SHORT], };
t[gl.RG16I] = { textureFormat: gl.RG_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [4], type: [gl.SHORT], };
t[gl.RG32UI] = { textureFormat: gl.RG_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [8], type: [gl.UNSIGNED_INT], };
t[gl.RG32I] = { textureFormat: gl.RG_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [8], type: [gl.INT], };
t[gl.RGB8] = { textureFormat: gl.RGB, colorRenderable: true, textureFilterable: true, bytesPerElement: [3], type: [gl.UNSIGNED_BYTE], };
t[gl.SRGB8] = { textureFormat: gl.RGB, colorRenderable: false, textureFilterable: true, bytesPerElement: [3], type: [gl.UNSIGNED_BYTE], };
t[gl.RGB565] = { textureFormat: gl.RGB, colorRenderable: true, textureFilterable: true, bytesPerElement: [3, 2], type: [gl.UNSIGNED_BYTE, gl.UNSIGNED_SHORT_5_6_5], };
t[gl.RGB8_SNORM] = { textureFormat: gl.RGB, colorRenderable: false, textureFilterable: true, bytesPerElement: [3], type: [gl.BYTE], };
t[gl.R11F_G11F_B10F] = { textureFormat: gl.RGB, colorRenderable: false, textureFilterable: true, bytesPerElement: [12, 6, 4], type: [gl.FLOAT, gl.HALF_FLOAT, gl.UNSIGNED_INT_10F_11F_11F_REV], };
t[gl.RGB9_E5] = { textureFormat: gl.RGB, colorRenderable: false, textureFilterable: true, bytesPerElement: [12, 6, 4], type: [gl.FLOAT, gl.HALF_FLOAT, gl.UNSIGNED_INT_5_9_9_9_REV], };
t[gl.RGB16F] = { textureFormat: gl.RGB, colorRenderable: false, textureFilterable: true, bytesPerElement: [12, 6], type: [gl.FLOAT, gl.HALF_FLOAT], };
t[gl.RGB32F] = { textureFormat: gl.RGB, colorRenderable: false, textureFilterable: false, bytesPerElement: [12], type: [gl.FLOAT], };
t[gl.RGB8UI] = { textureFormat: gl.RGB_INTEGER, colorRenderable: false, textureFilterable: false, bytesPerElement: [3], type: [gl.UNSIGNED_BYTE], };
t[gl.RGB8I] = { textureFormat: gl.RGB_INTEGER, colorRenderable: false, textureFilterable: false, bytesPerElement: [3], type: [gl.BYTE], };
t[gl.RGB16UI] = { textureFormat: gl.RGB_INTEGER, colorRenderable: false, textureFilterable: false, bytesPerElement: [6], type: [gl.UNSIGNED_SHORT], };
t[gl.RGB16I] = { textureFormat: gl.RGB_INTEGER, colorRenderable: false, textureFilterable: false, bytesPerElement: [6], type: [gl.SHORT], };
t[gl.RGB32UI] = { textureFormat: gl.RGB_INTEGER, colorRenderable: false, textureFilterable: false, bytesPerElement: [12], type: [gl.UNSIGNED_INT], };
t[gl.RGB32I] = { textureFormat: gl.RGB_INTEGER, colorRenderable: false, textureFilterable: false, bytesPerElement: [12], type: [gl.INT], };
t[gl.RGBA8] = { textureFormat: gl.RGBA, colorRenderable: true, textureFilterable: true, bytesPerElement: [4], type: [gl.UNSIGNED_BYTE], };
t[gl.SRGB8_ALPHA8] = { textureFormat: gl.RGBA, colorRenderable: true, textureFilterable: true, bytesPerElement: [4], type: [gl.UNSIGNED_BYTE], };
t[gl.RGBA8_SNORM] = { textureFormat: gl.RGBA, colorRenderable: false, textureFilterable: true, bytesPerElement: [4], type: [gl.BYTE], };
t[gl.RGB5_A1] = { textureFormat: gl.RGBA, colorRenderable: true, textureFilterable: true, bytesPerElement: [4, 2, 4], type: [gl.UNSIGNED_BYTE, gl.UNSIGNED_SHORT_5_5_5_1, gl.UNSIGNED_INT_2_10_10_10_REV], };
t[gl.RGBA4] = { textureFormat: gl.RGBA, colorRenderable: true, textureFilterable: true, bytesPerElement: [4, 2], type: [gl.UNSIGNED_BYTE, gl.UNSIGNED_SHORT_4_4_4_4], };
t[gl.RGB10_A2] = { textureFormat: gl.RGBA, colorRenderable: true, textureFilterable: true, bytesPerElement: [4], type: [gl.UNSIGNED_INT_2_10_10_10_REV], };
t[gl.RGBA16F] = { textureFormat: gl.RGBA, colorRenderable: false, textureFilterable: true, bytesPerElement: [16, 8], type: [gl.FLOAT, gl.HALF_FLOAT], };
t[gl.RGBA32F] = { textureFormat: gl.RGBA, colorRenderable: false, textureFilterable: false, bytesPerElement: [16], type: [gl.FLOAT], };
t[gl.RGBA8UI] = { textureFormat: gl.RGBA_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [4], type: [gl.UNSIGNED_BYTE], };
t[gl.RGBA8I] = { textureFormat: gl.RGBA_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [4], type: [gl.BYTE], };
t[gl.RGB10_A2UI] = { textureFormat: gl.RGBA_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [4], type: [gl.UNSIGNED_INT_2_10_10_10_REV], };
t[gl.RGBA16UI] = { textureFormat: gl.RGBA_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [8], type: [gl.UNSIGNED_SHORT], };
t[gl.RGBA16I] = { textureFormat: gl.RGBA_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [8], type: [gl.SHORT], };
t[gl.RGBA32I] = { textureFormat: gl.RGBA_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [16], type: [gl.INT], };
t[gl.RGBA32UI] = { textureFormat: gl.RGBA_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [16], type: [gl.UNSIGNED_INT], };
t[gl.R8] = { textureFormat: gl.RED, samplerType: FLOAT, depth: false, bytesPerElement: [1], type: [gl.UNSIGNED_BYTE], };
t[gl.R8_SNORM] = { textureFormat: gl.RED, samplerType: FLOAT, depth: false, bytesPerElement: [1], type: [gl.BYTE], };
t[gl.R16F] = { textureFormat: gl.RED, samplerType: FLOAT, depth: false, bytesPerElement: [4, 2], type: [gl.FLOAT, gl.HALF_FLOAT], };
t[gl.R32F] = { textureFormat: gl.RED, samplerType: FLOAT, depth: false, bytesPerElement: [4], type: [gl.FLOAT], };
t[gl.R8UI] = { textureFormat: gl.RED_INTEGER, samplerType: UNSIGNED, depth: false, bytesPerElement: [1], type: [gl.UNSIGNED_BYTE], };
t[gl.R8I] = { textureFormat: gl.RED_INTEGER, samplerType: SIGNED, depth: false, bytesPerElement: [1], type: [gl.BYTE], };
t[gl.R16UI] = { textureFormat: gl.RED_INTEGER, samplerType: UNSIGNED, depth: false, bytesPerElement: [2], type: [gl.UNSIGNED_SHORT], };
t[gl.R16I] = { textureFormat: gl.RED_INTEGER, samplerType: SIGNED, depth: false, bytesPerElement: [2], type: [gl.SHORT], };
t[gl.R32UI] = { textureFormat: gl.RED_INTEGER, samplerType: UNSIGNED, depth: false, bytesPerElement: [4], type: [gl.UNSIGNED_INT], };
t[gl.R32I] = { textureFormat: gl.RED_INTEGER, samplerType: SIGNED, depth: false, bytesPerElement: [4], type: [gl.INT], };
t[gl.RG8] = { textureFormat: gl.RG, samplerType: FLOAT, depth: false, bytesPerElement: [2], type: [gl.UNSIGNED_BYTE], };
t[gl.RG8_SNORM] = { textureFormat: gl.RG, samplerType: FLOAT, depth: false, bytesPerElement: [2], type: [gl.BYTE], };
t[gl.RG16F] = { textureFormat: gl.RG, samplerType: FLOAT, depth: false, bytesPerElement: [8, 4], type: [gl.FLOAT, gl.HALF_FLOAT], };
t[gl.RG32F] = { textureFormat: gl.RG, samplerType: FLOAT, depth: false, bytesPerElement: [8], type: [gl.FLOAT], };
t[gl.RG8UI] = { textureFormat: gl.RG_INTEGER, samplerType: UNSIGNED, depth: false, bytesPerElement: [2], type: [gl.UNSIGNED_BYTE], };
t[gl.RG8I] = { textureFormat: gl.RG_INTEGER, samplerType: SIGNED, depth: false, bytesPerElement: [2], type: [gl.BYTE], };
t[gl.RG16UI] = { textureFormat: gl.RG_INTEGER, samplerType: UNSIGNED, depth: false, bytesPerElement: [4], type: [gl.UNSIGNED_SHORT], };
t[gl.RG16I] = { textureFormat: gl.RG_INTEGER, samplerType: SIGNED, depth: false, bytesPerElement: [4], type: [gl.SHORT], };
t[gl.RG32UI] = { textureFormat: gl.RG_INTEGER, samplerType: UNSIGNED, depth: false, bytesPerElement: [8], type: [gl.UNSIGNED_INT], };
t[gl.RG32I] = { textureFormat: gl.RG_INTEGER, samplerType: SIGNED, depth: false, bytesPerElement: [8], type: [gl.INT], };
t[gl.RGB8] = { textureFormat: gl.RGB, samplerType: FLOAT, depth: false, bytesPerElement: [3], type: [gl.UNSIGNED_BYTE], };
t[gl.SRGB8] = { textureFormat: gl.RGB, samplerType: FLOAT, depth: false, bytesPerElement: [3], type: [gl.UNSIGNED_BYTE], };
t[gl.RGB565] = { textureFormat: gl.RGB, samplerType: FLOAT, depth: false, bytesPerElement: [3, 2], type: [gl.UNSIGNED_BYTE, gl.UNSIGNED_SHORT_5_6_5], };
t[gl.RGB8_SNORM] = { textureFormat: gl.RGB, samplerType: FLOAT, depth: false, bytesPerElement: [3], type: [gl.BYTE], };
t[gl.R11F_G11F_B10F] = { textureFormat: gl.RGB, samplerType: FLOAT, depth: false, bytesPerElement: [12, 6, 4], type: [gl.FLOAT, gl.HALF_FLOAT, gl.UNSIGNED_INT_10F_11F_11F_REV], };
t[gl.RGB9_E5] = { textureFormat: gl.RGB, samplerType: FLOAT, depth: false, bytesPerElement: [12, 6, 4], type: [gl.FLOAT, gl.HALF_FLOAT, gl.UNSIGNED_INT_5_9_9_9_REV], };
t[gl.RGB16F] = { textureFormat: gl.RGB, samplerType: FLOAT, depth: false, bytesPerElement: [12, 6], type: [gl.FLOAT, gl.HALF_FLOAT], };
t[gl.RGB32F] = { textureFormat: gl.RGB, samplerType: FLOAT, depth: false, bytesPerElement: [12], type: [gl.FLOAT], };
t[gl.RGB8UI] = { textureFormat: gl.RGB_INTEGER, samplerType: UNSIGNED, depth: false, bytesPerElement: [3], type: [gl.UNSIGNED_BYTE], };
t[gl.RGB8I] = { textureFormat: gl.RGB_INTEGER, samplerType: SIGNED, depth: false, bytesPerElement: [3], type: [gl.BYTE], };
t[gl.RGB16UI] = { textureFormat: gl.RGB_INTEGER, samplerType: UNSIGNED, depth: false, bytesPerElement: [6], type: [gl.UNSIGNED_SHORT], };
t[gl.RGB16I] = { textureFormat: gl.RGB_INTEGER, samplerType: SIGNED, depth: false, bytesPerElement: [6], type: [gl.SHORT], };
t[gl.RGB32UI] = { textureFormat: gl.RGB_INTEGER, samplerType: UNSIGNED, depth: false, bytesPerElement: [12], type: [gl.UNSIGNED_INT], };
t[gl.RGB32I] = { textureFormat: gl.RGB_INTEGER, samplerType: SIGNED, depth: false, bytesPerElement: [12], type: [gl.INT], };
t[gl.RGBA8] = { textureFormat: gl.RGBA, samplerType: FLOAT, depth: false, bytesPerElement: [4], type: [gl.UNSIGNED_BYTE], };
t[gl.SRGB8_ALPHA8] = { textureFormat: gl.RGBA, samplerType: FLOAT, depth: false, bytesPerElement: [4], type: [gl.UNSIGNED_BYTE], };
t[gl.RGBA8_SNORM] = { textureFormat: gl.RGBA, samplerType: FLOAT, depth: false, bytesPerElement: [4], type: [gl.BYTE], };
t[gl.RGB5_A1] = { textureFormat: gl.RGBA, samplerType: FLOAT, depth: false, bytesPerElement: [4, 2, 4], type: [gl.UNSIGNED_BYTE, gl.UNSIGNED_SHORT_5_5_5_1, gl.UNSIGNED_INT_2_10_10_10_REV], };
t[gl.RGBA4] = { textureFormat: gl.RGBA, samplerType: FLOAT, depth: false, bytesPerElement: [4, 2], type: [gl.UNSIGNED_BYTE, gl.UNSIGNED_SHORT_4_4_4_4], };
t[gl.RGB10_A2] = { textureFormat: gl.RGBA, samplerType: FLOAT, depth: false, bytesPerElement: [4], type: [gl.UNSIGNED_INT_2_10_10_10_REV], };
t[gl.RGBA16F] = { textureFormat: gl.RGBA, samplerType: FLOAT, depth: false, bytesPerElement: [16, 8], type: [gl.FLOAT, gl.HALF_FLOAT], };
t[gl.RGBA32F] = { textureFormat: gl.RGBA, samplerType: FLOAT, depth: false, bytesPerElement: [16], type: [gl.FLOAT], };
t[gl.RGBA8UI] = { textureFormat: gl.RGBA_INTEGER, samplerType: UNSIGNED, depth: false, bytesPerElement: [4], type: [gl.UNSIGNED_BYTE], };
t[gl.RGBA8I] = { textureFormat: gl.RGBA_INTEGER, samplerType: SIGNED, depth: false, bytesPerElement: [4], type: [gl.BYTE], };
t[gl.RGB10_A2UI] = { textureFormat: gl.RGBA_INTEGER, samplerType: UNSIGNED, depth: false, bytesPerElement: [4], type: [gl.UNSIGNED_INT_2_10_10_10_REV], };
t[gl.RGBA16UI] = { textureFormat: gl.RGBA_INTEGER, samplerType: UNSIGNED, depth: false, bytesPerElement: [8], type: [gl.UNSIGNED_SHORT], };
t[gl.RGBA16I] = { textureFormat: gl.RGBA_INTEGER, samplerType: SIGNED, depth: false, bytesPerElement: [8], type: [gl.SHORT], };
t[gl.RGBA32I] = { textureFormat: gl.RGBA_INTEGER, samplerType: SIGNED, depth: false, bytesPerElement: [16], type: [gl.INT], };
t[gl.RGBA32UI] = { textureFormat: gl.RGBA_INTEGER, samplerType: UNSIGNED, depth: false, bytesPerElement: [16], type: [gl.UNSIGNED_INT], };
// Sized Internal
t[gl.DEPTH_COMPONENT16] = { textureFormat: gl.DEPTH_COMPONENT, colorRenderable: true, textureFilterable: false, bytesPerElement: [2, 4], type: [gl.UNSIGNED_SHORT, gl.UNSIGNED_INT], };
t[gl.DEPTH_COMPONENT24] = { textureFormat: gl.DEPTH_COMPONENT, colorRenderable: true, textureFilterable: false, bytesPerElement: [4], type: [gl.UNSIGNED_INT], };
t[gl.DEPTH_COMPONENT32F] = { textureFormat: gl.DEPTH_COMPONENT, colorRenderable: true, textureFilterable: false, bytesPerElement: [4], type: [gl.FLOAT], };
t[gl.DEPTH24_STENCIL8] = { textureFormat: gl.DEPTH_STENCIL, colorRenderable: true, textureFilterable: false, bytesPerElement: [4], type: [gl.UNSIGNED_INT_24_8], };
t[gl.DEPTH32F_STENCIL8] = { textureFormat: gl.DEPTH_STENCIL, colorRenderable: true, textureFilterable: false, bytesPerElement: [4], type: [gl.FLOAT_32_UNSIGNED_INT_24_8_REV], };
// Note that samplerType is FLOAT for depth formats, not SHADOW. Shadow
// samplers are handled as a special case in the test code because they have
// special rules about TEXTURE_COMPARE_MODE.
t[gl.DEPTH_COMPONENT16] = { textureFormat: gl.DEPTH_COMPONENT, samplerType: FLOAT, depth: true, bytesPerElement: [2, 4], type: [gl.UNSIGNED_SHORT, gl.UNSIGNED_INT], };
t[gl.DEPTH_COMPONENT24] = { textureFormat: gl.DEPTH_COMPONENT, samplerType: FLOAT, depth: true, bytesPerElement: [4], type: [gl.UNSIGNED_INT], };
t[gl.DEPTH_COMPONENT32F] = { textureFormat: gl.DEPTH_COMPONENT, samplerType: FLOAT, depth: true, bytesPerElement: [4], type: [gl.FLOAT], };
t[gl.DEPTH24_STENCIL8] = { textureFormat: gl.DEPTH_STENCIL, samplerType: FLOAT, depth: true, bytesPerElement: [4], type: [gl.UNSIGNED_INT_24_8], };
t[gl.DEPTH32F_STENCIL8] = { textureFormat: gl.DEPTH_STENCIL, samplerType: FLOAT, depth: true, bytesPerElement: [4], type: [gl.FLOAT_32_UNSIGNED_INT_24_8_REV], };
// TODO: Compressed formats.
Object.keys(t).forEach(function(internalFormat) {
const info = t[internalFormat];
@ -143,62 +154,11 @@ const textureInternalFormatInfo = {};
});
}
const depthTextureFormats = [
gl.DEPTH_COMPONENT16,
gl.DEPTH_COMPONENT24,
gl.DEPTH_COMPONENT32F,
gl.DEPTH24_STENCIL8,
gl.DEPTH32F_STENCIL8,
];
const intTextureFormats = [
gl.R8I,
gl.R16I,
gl.R32I,
gl.RG8I,
gl.RG16I,
gl.RG32I,
gl.RGB8I,
gl.RGB16I,
gl.RGB32I,
gl.RGBA8I,
gl.RGBA16I,
gl.RGBA32I,
];
const unsignedIntTextureFormats = [
gl.R8UI,
gl.R16UI,
gl.R32UI,
gl.RG8UI,
gl.RG16UI,
gl.RG32UI,
gl.RGB8UI,
gl.RGB16UI,
gl.RGB32UI,
gl.RGBA8UI,
gl.RGB10_A2UI,
gl.RGBA16UI,
gl.RGBA32UI,
];
const floatTextureFormats = Object.keys(textureInternalFormatInfo).map(function(v) {
return parseInt(v);
}).filter(function(format) {
return intTextureFormats.indexOf(format) < 0 && unsignedIntTextureFormats.indexOf(format) < 0;
});
const floatSamplerTypes = [
{ type: 'sampler2D', uvType: 'vec2(0)', target: gl.TEXTURE_2D, },
{ type: 'sampler3D', uvType: 'vec3(0)', target: gl.TEXTURE_3D, },
{ type: 'samplerCube', uvType: 'vec3(0)', target: gl.TEXTURE_CUBE_MAP, },
{ type: 'sampler2DArray', uvType: 'vec3(0)', target: gl.TEXTURE_2D_ARRAY, },
// these sampler types should probably be tested separtely as they have
// various texParameter requirements
// { type: 'samplerCubeShadow', uvType: 'vec4(0)', target: gl.TEXTURE_, },
// { type: 'sampler2DShadow', uvType: 'vec3(0)', target: gl.TEXTURE_, },
// { type: 'sampler2DArrayShadow', uvType: 'vec4(0)', target: gl.TEXTURE_, },
];
const signedIntSamplerTypes = [
@ -215,6 +175,12 @@ const unsignedIntSamplerTypes = [
{ type: 'usampler2DArray', uvType: 'vec3(0)', target: gl.TEXTURE_2D_ARRAY, },
];
const shadowSamplerTypes = [
{ type: 'sampler2DShadow', uvType: 'vec3(0)', target: gl.TEXTURE_2D, },
{ type: 'samplerCubeShadow', uvType: 'vec4(0)', target: gl.TEXTURE_CUBE_MAP, },
{ type: 'sampler2DArrayShadow', uvType: 'vec4(0)', target: gl.TEXTURE_2D_ARRAY, },
]
/**
* Gets the number of bytes per element for a given internalFormat / type
* @param {number} internalFormat The internalFormat parameter from texImage2D etc..
@ -268,7 +234,7 @@ function runTest() {
targetInfo.textures = [];
Object.keys(textureInternalFormatInfo).forEach(function(internalFormat) {
internalFormat = parseInt(internalFormat);
const isDepthFormat = depthTextureFormats.indexOf(internalFormat) >= 0;
const isDepthFormat = textureInternalFormatInfo[internalFormat].depth;
if (target === gl.TEXTURE_3D && isDepthFormat) {
return;
}
@ -289,12 +255,33 @@ function runTest() {
});
});
testSamplerTypes(floatSamplerTypes, floatTextureFormats);
testSamplerTypes(signedIntSamplerTypes, intTextureFormats);
testSamplerTypes(unsignedIntSamplerTypes, unsignedIntTextureFormats);
const samplerObject = gl.createSampler();
gl.samplerParameteri(samplerObject, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
gl.samplerParameteri(samplerObject, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
gl.samplerParameteri(samplerObject, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.samplerParameteri(samplerObject, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
gl.samplerParameteri(samplerObject, gl.TEXTURE_WRAP_R, gl.CLAMP_TO_EDGE);
function testSamplerTypes(samplerTypes, compatibleFormats) {
samplerTypes.forEach(function(samplerInfo) {
// The rules implemented here are:
// Float samplers accept only float textures and normalized integer textures
// (signed or unsigned) and depth textures with TEXTURE_COMPARE_MODE set to
// NONE.
// Signed samplers accept only signed unnormalized integer textures.
// Unsigned samplers accept only unsigned unnormalized integer textures.
// Shadow samplers accept only depth textures with
// TEXTURE_COMPARE_MODE set to COMPARE_REF_TO_TEXTURE.
testSamplerType(FLOAT, floatSamplerTypes);
testSamplerType(SIGNED, signedIntSamplerTypes);
testSamplerType(UNSIGNED, unsignedIntSamplerTypes);
testSamplerType(SHADOW, shadowSamplerTypes);
function testSamplerType(samplerType, samplerInfos) {
samplerInfos.forEach(function(samplerInfo) {
debug(`\nchecking ${samplerInfo.type}`);
const program = wtu.setupProgram(gl, ['vshader', makeFragmentShader(samplerInfo.type, samplerInfo.uvType)], [], console.log.bind(console));
if (!program) {
@ -308,12 +295,47 @@ function runTest() {
targetInfo.textures.forEach(function(textureInfo) {
const internalFormat = textureInfo.internalFormat;
const desc = wtu.glEnumToString(gl, internalFormat);
const info = textureInternalFormatInfo[internalFormat];
// The texture object can have two values of TEXTURE_COMPARE_MODE: NONE or
// COMPARE_REF_TO_TEXTURE. However, the sampler can have three states:
// No sampler object bound, sampler object with NONE, and sampler object with
// COMPARE_REF_TO_TEXTURE. When a sampler object is bound, it overrides the
// texture object's state. We test 2*3=6 possible combinations of state.
// First test the three states that result in TEXTURE_COMPARE_MODE being NONE.
let expected = samplerType == info.samplerType ? gl.NONE : gl.INVALID_OPERATION;
gl.bindTexture(target, textureInfo.texture);
gl.drawArrays(gl.POINTS, 0, 1);
const expected = compatibleFormats.indexOf(internalFormat) < 0 ? gl.INVALID_OPERATION : gl.NONE;
wtu.glErrorShouldBe(gl, expected, `from draw with ${desc}`);
});
wtu.glErrorShouldBe(gl, expected, `${desc} texture state NONE, no sampler object`);
gl.bindSampler(0, samplerObject);
gl.samplerParameteri(samplerObject, gl.TEXTURE_COMPARE_MODE, gl.NONE);
gl.drawArrays(gl.POINTS, 0, 1);
wtu.glErrorShouldBe(gl, expected, `${desc} texture state NONE, sampler state NONE`);
gl.texParameteri(target, gl.TEXTURE_COMPARE_MODE, gl.COMPARE_REF_TO_TEXTURE);
gl.drawArrays(gl.POINTS, 0, 1);
wtu.glErrorShouldBe(gl, expected, `${desc} texture state COMPARE_REF_TO_TEXTURE, sampler state NONE`);
// Now test test the three states that result in TEXTURE_COMPARE_MODE being COMPARE_REF_TO_TEXTURE.
if (info.depth) {
expected = samplerType == SHADOW ? gl.NONE : gl.INVALID_OPERATION;
}
gl.bindSampler(0, null);
gl.drawArrays(gl.POINTS, 0, 1);
wtu.glErrorShouldBe(gl, expected, `${desc} texture state COMPARE_REF_TO_TEXTURE, no sampler object`);
gl.bindSampler(0, samplerObject);
gl.samplerParameteri(samplerObject, gl.TEXTURE_COMPARE_MODE, gl.COMPARE_REF_TO_TEXTURE);
gl.drawArrays(gl.POINTS, 0, 1);
wtu.glErrorShouldBe(gl, expected, `${desc} texture state COMPARE_REF_TO_TEXTURE, sampler state COMPARE_REF_TO_TEXTURE`);
gl.texParameteri(target, gl.TEXTURE_COMPARE_MODE, gl.NONE);
gl.drawArrays(gl.POINTS, 0, 1);
wtu.glErrorShouldBe(gl, expected, `${desc} texture state NONE, sampler state COMPARE_REF_TO_TEXTURE`);
gl.bindSampler(0, null);
});
});
};
}

Просмотреть файл

@ -1 +1,2 @@
vertex-array-object.html
--min-version 2.0.1 vertex-array-object-and-disabled-attributes.html

Просмотреть файл

@ -0,0 +1,152 @@
<!--
/*
** Copyright (c) 2018 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 Disabled Vertex Array Object and Disabled Attributes Test</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>
<canvas id="example" width="50" height="50">
</canvas>
<div id="description"></div>
<div id="console"></div>
<script id="singlevshader" type="x-shader/x-vertex">
attribute vec4 position;
void main() {
gl_Position = position;
}
</script>
<script id="singlefshader" type="x-shader/x-fragment">
void main() {
gl_FragColor = vec4(1, 0, 0, 1);
}
</script>
<script id="dualvshader" type="x-shader/x-vertex">#version 300 es
in vec4 position;
in vec4 color;
out vec4 varyColor;
void main() {
gl_Position = position;
varyColor = color;
}
</script>
<script id="dualfshader" type="x-shader/x-fragment">#version 300 es
precision mediump float;
in vec4 varyColor;
out vec4 colorOut;
void main() {
colorOut = varyColor;
}
</script>
<script>
// Test that switching VAOs keeps the disabled "current value" attributes up-to-date.
// Based on ANGLE test (StateChangeTestES3, VertexArrayObjectAndDisabledAttributes) from https://github.com/google/angle/blob/f7f0b8c3ab21c52cc2915048959361cf628d95f0/src/tests/gl_tests/StateChangeTest.cpp
"use strict";
var wtu = WebGLTestUtils;
description();
var gl = wtu.create3DContext("example", undefined, 2);
var singleProgram = wtu.setupProgram(gl, ['singlevshader', 'singlefshader']);
var dualProgram = wtu.setupProgram(gl, ['dualvshader', 'dualfshader']);
var positionLocation = gl.getAttribLocation(dualProgram, "position");
var colorLocation = gl.getAttribLocation(dualProgram, "color");
var singlePositionLocation = gl.getAttribLocation(singleProgram, "position");
gl.useProgram(singleProgram);
var positions = new Float32Array([
-1, 1,
-1, -1,
1, -1,
-1, 1,
1, -1,
1, 1
]);
var positionBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
gl.bufferData(gl.ARRAY_BUFFER, positions, gl.STATIC_DRAW);
var vertexArray = gl.createVertexArray();
gl.bindVertexArray(vertexArray);
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
gl.vertexAttribPointer(singlePositionLocation, 2, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(singlePositionLocation);
gl.drawArrays(gl.TRIANGLES, 0, 6);
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no errors");
wtu.checkCanvas(gl, [255, 0, 0, 255], "should be red");
gl.bindVertexArray(null);
gl.useProgram(dualProgram);
gl.vertexAttribPointer(positionLocation, 2, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(positionLocation);
var greenBuffer = gl.createBuffer();
var green = new Uint8Array(4 * 6);
for (var i = 0; i < 6; ++i) {
var ci = i * 4;
green[ci] = 0;
green[ci + 1] = 255;
green[ci + 2] = 0;
green[ci + 3] = 255;
}
gl.bindBuffer(gl.ARRAY_BUFFER, greenBuffer);
gl.bufferData(gl.ARRAY_BUFFER, green, gl.STATIC_DRAW);
gl.vertexAttribPointer(colorLocation, 4, gl.UNSIGNED_BYTE, true, 0, 0);
gl.enableVertexAttribArray(colorLocation);
gl.drawArrays(gl.TRIANGLES, 0, 6);
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no errors");
wtu.checkCanvas(gl, [0, 255, 0, 255], "should be green");
gl.bindVertexArray(vertexArray);
gl.drawArrays(gl.TRIANGLES, 0, 6);
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no errors");
wtu.checkCanvas(gl, [0, 0, 0, 255], "should be black");
var successfullyParsed = true;
</script>
<script src="../../js/js-test-post.js"></script>
</body>
</html>

Просмотреть файл

@ -95,6 +95,9 @@ goog.scope(function() {
// Please see https://android.googlesource.com/platform/external/deqp/+/master/android/cts/master/src/gles3-driver-issues.txt
_skip("texture_functions.textureprojlodoffset.isampler3d_vertex");
_skip("texture_functions.texturegrad.samplercubeshadow*");
// Please see https://android.googlesource.com/platform/external/deqp/+/40ff528%5E%21/
// and https://bugs.chromium.org/p/angleproject/issues/detail?id=3094
_skip("texture_functions.texturelodoffset.sampler3d_float_vertex");
// https://android.googlesource.com/platform/external/deqp/+/0c1f83aee4709eef7ef2a3edd384f9c192f476fd/android/cts/master/src/gles3-hw-issues.txt#801
_setReason("Tricky blit rects can result in imperfect copies on some HW.");
@ -118,13 +121,6 @@ goog.scope(function() {
_skip("blit.rect.nearest_consistency_out_of_bounds_min_reverse_src_x");
_skip("blit.rect.nearest_consistency_out_of_bounds_min_reverse_src_y");
_setReason("Tricky blit rects can result in imperfect copies on Mac Intel driver.");
// crbug.com/658724
// deqp/functional/gles3/framebufferblit/rect_03.html
_skip("blit.rect.nearest_consistency_mag_reverse_src_dst_y");
// deqp/functional/gles3/framebufferblit/rect_04.html
_skip("blit.rect.nearest_consistency_min_reverse_src_dst_y");
// https://android.googlesource.com/platform/external/deqp/+/0c1f83aee4709eef7ef2a3edd384f9c192f476fd/android/cts/master/src/gles3-driver-issues.txt#381
_setReason("Tricky blit rects can result in imperfect copies on some drivers.");
_skip("blit.rect.out_of_bounds_linear");
@ -210,6 +206,25 @@ goog.scope(function() {
// Also see conformance2/rendering/blitframebuffer-stencil-only.html for 2.0.1 test.
_skip("blit.depth_stencil.depth24_stencil8_scale");
_skip("blit.depth_stencil.depth24_stencil8_stencil_only");
_setReason("Removed from native dEQP mustpass. Not passable on Adreno.");
// These tests have been skipped in native dEQP since 2015:
// https://android.googlesource.com/platform/external/deqp/+/ea026b329e6bf73f109cda914c90f08d5f7a5b8d
// They do not pass on Android/Qualcomm (Google Pixel 1, Pixel 3).
// It's not clear if the tests or the hardware are out-of-spec, but there's nothing we can do about it right now.
// See also: crbug.com/695679
_skip("derivate.dfdy.fbo_float.float_highp");
_skip("derivate.dfdy.fbo_float.vec2_highp");
_skip("derivate.dfdy.fbo_float.vec3_highp");
_skip("derivate.dfdy.fbo_float.vec4_highp");
_skip("derivate.dfdy.nicest.fbo_float.float_highp");
_skip("derivate.dfdy.nicest.fbo_float.vec2_highp");
_skip("derivate.dfdy.nicest.fbo_float.vec3_highp");
_skip("derivate.dfdy.nicest.fbo_float.vec4_highp");
_skip("derivate.dfdy.fastest.fbo_float.float_highp");
_skip("derivate.dfdy.fastest.fbo_float.vec2_highp");
_skip("derivate.dfdy.fastest.fbo_float.vec3_highp");
_skip("derivate.dfdy.fastest.fbo_float.vec4_highp");
} // if (!runSkippedTests)
/*

Просмотреть файл

@ -31,20 +31,24 @@ goog.scope(function() {
var tcuTestCase = framework.common.tcuTestCase;
var tcuSkipList = framework.common.tcuSkipList;
tcuTestCase.getQueryVal = function(key) {
const queryVars = window.location.search.substring(1).split('&');
for (let kv of queryVars) {
kv = kv.split('=');
if (decodeURIComponent(kv[0]) === key)
return decodeURIComponent(kv[1]);
}
return null;
};
tcuTestCase.isQuickMode = () => tcuTestCase.getQueryVal('quick') === '1';
tcuTestCase.isQuietMode = () => tcuTestCase.getQueryVal('quiet') === '1';
/**
* Reads the filter parameter from the URL to filter tests.
* @return {?string }
*/
tcuTestCase.getFilter = function() {
var queryVars = window.location.search.substring(1).split('&');
for (var i = 0; i < queryVars.length; i++) {
var value = queryVars[i].split('=');
if (decodeURIComponent(value[0]) === 'filter')
return decodeURIComponent(value[1]);
}
return null;
};
tcuTestCase.getFilter = () => tcuTestCase.getQueryVal('filter');
/**
* Indicates the state of an iteration operation.
@ -128,6 +132,9 @@ goog.scope(function() {
*/
tcuTestCase.Runner.prototype.terminate = function() {
finishTest();
if (!tcuTestCase.isQuietMode()) {
console.log('finishTest() after (in ms):', performance.now());
}
};
tcuTestCase.runner = new tcuTestCase.Runner();

Просмотреть файл

@ -1,4 +1,8 @@
--min-version 2.0.1 builtinprecision/00_test_list.txt
# The builtinprecision tests are not correct. Errors were introduced when
# porting the tests from C++ to JavaScript. Tests that fail here pass in
# the C++ version of dEQP ported to WASM. The tests are disabled here until
# they can be fixed.
# --min-version 2.0.1 builtinprecision/00_test_list.txt
draw/00_test_list.txt
fbocolorbuffer/00_test_list.txt
fboinvalidate/00_test_list.txt

Просмотреть файл

@ -54,6 +54,19 @@ var gluShaderUtil = framework.opengl.gluShaderUtil;
/** @const*/ var MIN_THRESHOLD = new tcuRGBA.RGBA([12, 12, 12, 12]);
let canvasWH = 256;
let texPotSize = [128, 128, 5];
let texNpotSizeA = [129, 117];
let texNpotSizeB = [99, 128];
if (tcuTestCase.isQuickMode()) {
canvasWH = 32;
texPotSize = [16, 16, 5];
texNpotSizeA = [12, 11];
texNpotSizeB = [9, 16];
}
const texW = texPotSize[0];
const texH = texPotSize[1];
var setParentClass = function(child, parent) {
child.prototype = Object.create(parent.prototype);
child.prototype.constructor = child;
@ -344,8 +357,6 @@ es3fFboColorbufferTests.FboColorMultiTex2DCase.prototype.render = function(dst)
for (var ndx = 0; ndx < 2; ndx++) {
var format = gl.RGBA;
var dataType = gl.UNSIGNED_BYTE;
var texW = 128;
var texH = 128;
var tmpTex;
var fbo = ndx ? fbo1 : fbo0;
var viewport = ndx ? this.m_tex1Size : this.m_tex0Size;
@ -486,8 +497,6 @@ es3fFboColorbufferTests.FboColorTexCubeCase.prototype.render = function(dst) {
var face = order[ndx];
var format = gl.RGBA;
var dataType = gl.UNSIGNED_BYTE;
var texW = 128;
var texH = 128;
var tmpTex;
var fbo = fbos[face];
var viewport = this.m_texSize;
@ -612,8 +621,6 @@ es3fFboColorbufferTests.FboColorTex2DArrayCase.prototype.preCheck = function() {
var layer = order[ndx];
var format = gl.RGBA;
var dataType = gl.UNSIGNED_BYTE;
var texW = 128;
var texH = 128;
var fbo = fbos[layer];
var viewport = this.m_texSize;
var data = new tcuTexture.TextureLevel(gluTextureUtil.mapGLTransferFormat(format, dataType), texW, texH, 1);
@ -737,8 +744,6 @@ es3fFboColorbufferTests.FboColorTex3DCase.prototype.preCheck = function() {
var layer = order[ndx];
var format = gl.RGBA;
var dataType = gl.UNSIGNED_BYTE;
var texW = 128;
var texH = 128;
var fbo = fbos[layer];
var viewport = this.m_texSize;
var data = new tcuTexture.TextureLevel(gluTextureUtil.mapGLTransferFormat(format, dataType), texW, texH, 1);
@ -848,8 +853,6 @@ es3fFboColorbufferTests.FboBlendCase.prototype.preCheck = function() {
// Fill framebuffer with grid pattern.
var format = gl.RGBA;
var dataType = gl.UNSIGNED_BYTE;
var texW = 128;
var texH = 128;
var data = new tcuTexture.TextureLevel(gluTextureUtil.mapGLTransferFormat(format, dataType), texW, texH, 1);
tcuTextureUtil.fillWithGrid(data.getAccess(), 8, [0.2, 0.7, 0.1, 1.0], [0.7, 0.1, 0.5, 0.8]);
@ -943,7 +946,7 @@ es3fFboColorbufferTests.FboColorbufferTests.prototype.init = function() {
for (var ndx = 0; ndx < colorFormats.length; ndx++) {
clearGroup.addChild(new es3fFboColorbufferTests.FboColorClearCase(
es3fFboTestUtil.getFormatName(colorFormats[ndx]), "", colorFormats[ndx], 129, 117));
es3fFboTestUtil.getFormatName(colorFormats[ndx]), "", colorFormats[ndx], texNpotSizeA[0], texNpotSizeA[1]));
}
var numGroups = 6;
@ -956,7 +959,7 @@ es3fFboColorbufferTests.FboColorbufferTests.prototype.init = function() {
}
for (var ndx = 0; ndx < colorFormats.length; ndx++) {
tex2DGroup[ndx % numGroups].addChild(new es3fFboColorbufferTests.FboColorMultiTex2DCase(
es3fFboTestUtil.getFormatName(colorFormats[ndx]), "", colorFormats[ndx], [129, 117], colorFormats[ndx], [99, 128]));
es3fFboTestUtil.getFormatName(colorFormats[ndx]), "", colorFormats[ndx], texNpotSizeA, colorFormats[ndx], texNpotSizeB));
}
// .texcube
@ -967,7 +970,7 @@ es3fFboColorbufferTests.FboColorbufferTests.prototype.init = function() {
}
for (var ndx = 0; ndx < colorFormats.length; ndx++) {
texCubeGroup[ndx % numGroups].addChild(new es3fFboColorbufferTests.FboColorTexCubeCase(
es3fFboTestUtil.getFormatName(colorFormats[ndx]), "", colorFormats[ndx], [128, 128]));
es3fFboTestUtil.getFormatName(colorFormats[ndx]), "", colorFormats[ndx], texPotSize));
}
// .tex2darray
@ -978,7 +981,7 @@ es3fFboColorbufferTests.FboColorbufferTests.prototype.init = function() {
}
for (var ndx = 0; ndx < colorFormats.length; ndx++) {
tex2DArrayGroup[ndx % numGroups].addChild(new es3fFboColorbufferTests.FboColorTex2DArrayCase(
es3fFboTestUtil.getFormatName(colorFormats[ndx]), "", colorFormats[ndx], [128, 128, 5]));
es3fFboTestUtil.getFormatName(colorFormats[ndx]), "", colorFormats[ndx], texPotSize));
}
// .tex3d
@ -989,7 +992,7 @@ es3fFboColorbufferTests.FboColorbufferTests.prototype.init = function() {
}
for (var ndx = 0; ndx < colorFormats.length; ndx++) {
tex3DGroup[ndx % numGroups].addChild(new es3fFboColorbufferTests.FboColorTex3DCase(
es3fFboTestUtil.getFormatName(colorFormats[ndx]), "", colorFormats[ndx], [128, 128, 5]));
es3fFboTestUtil.getFormatName(colorFormats[ndx]), "", colorFormats[ndx], texPotSize));
}
// .blend
@ -1008,7 +1011,7 @@ es3fFboColorbufferTests.FboColorbufferTests.prototype.init = function() {
continue; // Blending is not supported.
blendGroup.addChild(new es3fFboColorbufferTests.FboBlendCase(fmtName + "_src_over", "", format,
[127, 111], gl.FUNC_ADD, gl.FUNC_ADD, gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA, gl.ZERO, gl.ONE));
texNpotSizeA, gl.FUNC_ADD, gl.FUNC_ADD, gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA, gl.ZERO, gl.ONE));
}
};
@ -1018,6 +1021,11 @@ es3fFboColorbufferTests.FboColorbufferTests.prototype.init = function() {
*/
es3fFboColorbufferTests.run = function(context, range) {
gl = context;
const canvas = gl.canvas;
canvas.width = canvasWH;
canvas.height = canvasWH;
//Set up Test Root parameters
var state = tcuTestCase.runner;
state.setRoot(new es3fFboColorbufferTests.FboColorbufferTests());

Просмотреть файл

@ -100,12 +100,7 @@ es3fLifetimeTests.ScaleProgram.prototype.draw = function(vao, scale, tf, dst) {
es3fLifetimeTests.ScaleProgram.prototype.setPos = function(buffer, vao) {
gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
gl.bindVertexArray(vao);
if (buffer) {
gl.vertexAttribPointer(this.m_posLoc, NUM_COMPONENTS, gl.FLOAT, false, 0, 0);
} else {
var name = gl.getVertexAttrib(this.m_posLoc, gl.VERTEX_ATTRIB_ARRAY_BUFFER_BINDING);
gl.deleteBuffer(name);
}
gl.vertexAttribPointer(this.m_posLoc, NUM_COMPONENTS, gl.FLOAT, false, 0, 0);
gl.bindVertexArray(null);
gl.bindBuffer(gl.ARRAY_BUFFER, null);
};

Просмотреть файл

@ -306,13 +306,13 @@ goog.scope(function() {
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, bufElements);
bufferedLogToConsole('gl.INVALID_ENUM is generated if mode is not an accepted value.');
gl.drawElements(-1, 1, gl.UNSIGNED_BYTE, vertices);
gl.drawElements(-1, 0, gl.UNSIGNED_BYTE, vertices);
this.expectError(gl.INVALID_ENUM);
bufferedLogToConsole('gl.INVALID_ENUM is generated if type is not one of the accepted values.');
gl.drawElements(gl.POINTS, 1, -1, vertices);
gl.drawElements(gl.POINTS, 0, -1, vertices);
this.expectError(gl.INVALID_ENUM);
gl.drawElements(gl.POINTS, 1, gl.FLOAT, vertices);
gl.drawElements(gl.POINTS, 0, gl.FLOAT, vertices);
this.expectError(gl.INVALID_ENUM);
bufferedLogToConsole('gl.INVALID_VALUE is generated if count is negative.');
@ -323,7 +323,7 @@ goog.scope(function() {
fbo = gl.createFramebuffer();
gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
gl.checkFramebufferStatus(gl.FRAMEBUFFER);
gl.drawElements(gl.POINTS, 1, gl.UNSIGNED_BYTE, vertices);
gl.drawElements(gl.POINTS, 0, gl.UNSIGNED_BYTE, vertices);
this.expectError(gl.INVALID_FRAMEBUFFER_OPERATION);
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
gl.deleteFramebuffer(fbo);
@ -345,13 +345,13 @@ goog.scope(function() {
gl.beginTransformFeedback (gl.POINTS);
this.expectError (gl.NO_ERROR);
gl.drawElements (gl.POINTS, 1, gl.UNSIGNED_BYTE, vertices);
gl.drawElements (gl.POINTS, 0, gl.UNSIGNED_BYTE, vertices);
this.expectError (gl.INVALID_OPERATION);
gl.bufferData (gl.ELEMENT_ARRAY_BUFFER, 32, gl.STATIC_DRAW);
gl.pauseTransformFeedback();
gl.drawElements (gl.POINTS, 1, gl.UNSIGNED_BYTE, vertices);
gl.drawElements (gl.POINTS, 0, gl.UNSIGNED_BYTE, vertices);
this.expectError (gl.NO_ERROR);
gl.endTransformFeedback ();
@ -373,7 +373,7 @@ goog.scope(function() {
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, bufElements);
bufferedLogToConsole('gl.INVALID_OPERATION is generated if gl.useProgram(null) was set.');
gl.drawElements(gl.POINTS, 1, gl.UNSIGNED_BYTE, vertices);
gl.drawElements(gl.POINTS, 0, gl.UNSIGNED_BYTE, vertices);
this.expectError(gl.INVALID_OPERATION);
gl.deleteBuffer(bufElements);
@ -392,13 +392,13 @@ goog.scope(function() {
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, bufElements);
bufferedLogToConsole('gl.INVALID_ENUM is generated if mode is not an accepted value.');
gl.drawElements(-1, 1, gl.UNSIGNED_BYTE, vertices);
gl.drawElements(-1, 0, gl.UNSIGNED_BYTE, vertices);
this.expectError(gl.INVALID_ENUM);
bufferedLogToConsole('gl.INVALID_ENUM is generated if type is not one of the accepted values.');
gl.drawElements(gl.TRIANGLES, 1, -1, vertices);
gl.drawElements(gl.TRIANGLES, 0, -1, vertices);
this.expectError(gl.INVALID_ENUM);
gl.drawElements(gl.TRIANGLES, 1, gl.FLOAT, vertices);
gl.drawElements(gl.TRIANGLES, 0, gl.FLOAT, vertices);
this.expectError(gl.INVALID_ENUM);
bufferedLogToConsole('gl.INVALID_VALUE is generated if count is negative.');
@ -409,7 +409,7 @@ goog.scope(function() {
fbo = gl.createFramebuffer();
gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
gl.checkFramebufferStatus(gl.FRAMEBUFFER);
gl.drawElements(gl.TRIANGLES, 1, gl.UNSIGNED_BYTE, vertices);
gl.drawElements(gl.TRIANGLES, 0, gl.UNSIGNED_BYTE, vertices);
this.expectError(gl.INVALID_FRAMEBUFFER_OPERATION);
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
gl.deleteFramebuffer(fbo);
@ -431,13 +431,13 @@ goog.scope(function() {
gl.beginTransformFeedback (gl.TRIANGLES);
this.expectError (gl.NO_ERROR);
gl.drawElements (gl.TRIANGLES, 1, gl.UNSIGNED_BYTE, vertices);
gl.drawElements (gl.TRIANGLES, 0, gl.UNSIGNED_BYTE, vertices);
this.expectError (gl.INVALID_OPERATION);
gl.bufferData (gl.ELEMENT_ARRAY_BUFFER, 32, gl.STATIC_DRAW);
gl.pauseTransformFeedback();
gl.drawElements (gl.TRIANGLES, 1, gl.UNSIGNED_BYTE, vertices);
gl.drawElements (gl.TRIANGLES, 0, gl.UNSIGNED_BYTE, vertices);
this.expectError (gl.NO_ERROR);
gl.endTransformFeedback ();
@ -553,26 +553,26 @@ goog.scope(function() {
this.expectError(gl.NO_ERROR);
bufferedLogToConsole('gl.INVALID_ENUM is generated if mode is not an accepted value.');
gl.drawElementsInstanced(-1, 1, gl.UNSIGNED_BYTE, vertices, 1);
gl.drawElementsInstanced(-1, 0, gl.UNSIGNED_BYTE, vertices, 1);
this.expectError(gl.INVALID_ENUM);
bufferedLogToConsole('gl.INVALID_ENUM is generated if type is not one of the accepted values.');
gl.drawElementsInstanced(gl.POINTS, 1, -1, vertices, 1);
gl.drawElementsInstanced(gl.POINTS, 0, -1, vertices, 1);
this.expectError(gl.INVALID_ENUM);
gl.drawElementsInstanced(gl.POINTS, 1, gl.FLOAT, vertices, 1);
gl.drawElementsInstanced(gl.POINTS, 0, gl.FLOAT, vertices, 1);
this.expectError(gl.INVALID_ENUM);
bufferedLogToConsole('gl.INVALID_VALUE is generated if count or primcount are negative.');
gl.drawElementsInstanced(gl.POINTS, -1, gl.UNSIGNED_BYTE, vertices, 1);
gl.drawElementsInstanced(gl.POINTS, -1, gl.UNSIGNED_BYTE, vertices, 0);
this.expectError(gl.INVALID_VALUE);
gl.drawElementsInstanced(gl.POINTS, 11, gl.UNSIGNED_BYTE, vertices, -1);
gl.drawElementsInstanced(gl.POINTS, 0, gl.UNSIGNED_BYTE, vertices, -1);
this.expectError(gl.INVALID_VALUE);
bufferedLogToConsole('gl.INVALID_FRAMEBUFFER_OPERATION is generated if the currently bound framebuffer is not framebuffer complete.');
fbo = gl.createFramebuffer();
gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
gl.checkFramebufferStatus(gl.FRAMEBUFFER);
gl.drawElementsInstanced(gl.POINTS, 1, gl.UNSIGNED_BYTE, vertices, 1);
gl.drawElementsInstanced(gl.POINTS, 0, gl.UNSIGNED_BYTE, vertices, 1);
this.expectError(gl.INVALID_FRAMEBUFFER_OPERATION);
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
gl.deleteFramebuffer(fbo);
@ -594,13 +594,13 @@ goog.scope(function() {
gl.beginTransformFeedback (gl.POINTS);
this.expectError (gl.NO_ERROR);
gl.drawElementsInstanced (gl.POINTS, 1, gl.UNSIGNED_BYTE, vertices, 1);
gl.drawElementsInstanced (gl.POINTS, 0, gl.UNSIGNED_BYTE, vertices, 1);
this.expectError (gl.INVALID_OPERATION);
gl.bufferData (gl.ELEMENT_ARRAY_BUFFER, 32, gl.STATIC_DRAW);
gl.pauseTransformFeedback();
gl.drawElementsInstanced (gl.POINTS, 1, gl.UNSIGNED_BYTE, vertices, 1);
gl.drawElementsInstanced (gl.POINTS, 0, gl.UNSIGNED_BYTE, vertices, 1);
this.expectError (gl.NO_ERROR);
gl.endTransformFeedback ();
@ -626,7 +626,7 @@ goog.scope(function() {
this.expectError(gl.NO_ERROR);
bufferedLogToConsole('gl.INVALID_OPERATION is generated if gl.useProgram(null) is set.');
gl.drawElementsInstanced(gl.POINTS, 1, gl.UNSIGNED_BYTE, vertices, 1);
gl.drawElementsInstanced(gl.POINTS, 0, gl.UNSIGNED_BYTE, vertices, 1);
this.expectError(gl.INVALID_OPERATION);
gl.deleteBuffer(bufElements);
@ -649,26 +649,26 @@ goog.scope(function() {
this.expectError(gl.NO_ERROR);
bufferedLogToConsole('gl.INVALID_ENUM is generated if mode is not an accepted value.');
gl.drawElementsInstanced(-1, 1, gl.UNSIGNED_BYTE, vertices, 1);
gl.drawElementsInstanced(-1, 0, gl.UNSIGNED_BYTE, vertices, 1);
this.expectError(gl.INVALID_ENUM);
bufferedLogToConsole('gl.INVALID_ENUM is generated if type is not one of the accepted values.');
gl.drawElementsInstanced(gl.TRIANGLES, 1, -1, vertices, 1);
gl.drawElementsInstanced(gl.TRIANGLES, 0, -1, vertices, 1);
this.expectError(gl.INVALID_ENUM);
gl.drawElementsInstanced(gl.TRIANGLES, 1, gl.FLOAT, vertices, 1);
gl.drawElementsInstanced(gl.TRIANGLES, 0, gl.FLOAT, vertices, 1);
this.expectError(gl.INVALID_ENUM);
bufferedLogToConsole('gl.INVALID_VALUE is generated if count or primcount are negative.');
gl.drawElementsInstanced(gl.TRIANGLES, -1, gl.UNSIGNED_BYTE, vertices, 1);
gl.drawElementsInstanced(gl.TRIANGLES, -1, gl.UNSIGNED_BYTE, vertices, 0);
this.expectError(gl.INVALID_VALUE);
gl.drawElementsInstanced(gl.TRIANGLES, 11, gl.UNSIGNED_BYTE, vertices, -1);
gl.drawElementsInstanced(gl.TRIANGLES, 0, gl.UNSIGNED_BYTE, vertices, -1);
this.expectError(gl.INVALID_VALUE);
bufferedLogToConsole('gl.INVALID_FRAMEBUFFER_OPERATION is generated if the currently bound framebuffer is not framebuffer complete.');
fbo = gl.createFramebuffer();
gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
gl.checkFramebufferStatus(gl.FRAMEBUFFER);
gl.drawElementsInstanced(gl.TRIANGLES, 1, gl.UNSIGNED_BYTE, vertices, 1);
gl.drawElementsInstanced(gl.TRIANGLES, 0, gl.UNSIGNED_BYTE, vertices, 1);
this.expectError(gl.INVALID_FRAMEBUFFER_OPERATION);
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
gl.deleteFramebuffer(fbo);
@ -690,13 +690,13 @@ goog.scope(function() {
gl.beginTransformFeedback (gl.TRIANGLES);
this.expectError (gl.NO_ERROR);
gl.drawElementsInstanced (gl.TRIANGLES, 1, gl.UNSIGNED_BYTE, vertices, 1);
gl.drawElementsInstanced (gl.TRIANGLES, 0, gl.UNSIGNED_BYTE, vertices, 1);
this.expectError (gl.INVALID_OPERATION);
gl.bufferData (gl.ELEMENT_ARRAY_BUFFER, 32, gl.STATIC_DRAW);
gl.pauseTransformFeedback();
gl.drawElementsInstanced (gl.TRIANGLES, 1, gl.UNSIGNED_BYTE, vertices, 1);
gl.drawElementsInstanced (gl.TRIANGLES, 0, gl.UNSIGNED_BYTE, vertices, 1);
this.expectError (gl.NO_ERROR);
gl.endTransformFeedback ();
@ -723,13 +723,13 @@ goog.scope(function() {
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, bufElements);
bufferedLogToConsole('gl.INVALID_ENUM is generated if mode is not an accepted value.');
gl.drawRangeElements(-1, 0, 1, 1, gl.UNSIGNED_BYTE, vertices);
gl.drawRangeElements(-1, 0, 1, 0, gl.UNSIGNED_BYTE, vertices);
this.expectError(gl.INVALID_ENUM);
bufferedLogToConsole('gl.INVALID_ENUM is generated if type is not one of the accepted values.');
gl.drawRangeElements(gl.POINTS, 0, 1, 1, -1, vertices);
gl.drawRangeElements(gl.POINTS, 0, 1, 0, -1, vertices);
this.expectError(gl.INVALID_ENUM);
gl.drawRangeElements(gl.POINTS, 0, 1, 1, gl.FLOAT, vertices);
gl.drawRangeElements(gl.POINTS, 0, 1, 0, gl.FLOAT, vertices);
this.expectError(gl.INVALID_ENUM);
bufferedLogToConsole('gl.INVALID_VALUE is generated if count is negative.');
@ -737,14 +737,14 @@ goog.scope(function() {
this.expectError(gl.INVALID_VALUE);
bufferedLogToConsole('gl.INVALID_VALUE is generated if end < start.');
gl.drawRangeElements(gl.POINTS, 1, 0, 1, gl.UNSIGNED_BYTE, vertices);
gl.drawRangeElements(gl.POINTS, 1, 0, 0, gl.UNSIGNED_BYTE, vertices);
this.expectError(gl.INVALID_VALUE);
bufferedLogToConsole('gl.INVALID_FRAMEBUFFER_OPERATION is generated if the currently bound framebuffer is not framebuffer complete.');
fbo = gl.createFramebuffer();
gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
gl.checkFramebufferStatus(gl.FRAMEBUFFER);
gl.drawRangeElements(gl.POINTS, 0, 1, 1, gl.UNSIGNED_BYTE, vertices);
gl.drawRangeElements(gl.POINTS, 0, 1, 0, gl.UNSIGNED_BYTE, vertices);
this.expectError(gl.INVALID_FRAMEBUFFER_OPERATION);
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
gl.deleteFramebuffer(fbo);
@ -766,13 +766,13 @@ goog.scope(function() {
gl.beginTransformFeedback (gl.POINTS);
this.expectError (gl.NO_ERROR);
gl.drawRangeElements (gl.POINTS, 0, 1, 1, gl.UNSIGNED_BYTE, vertices);
gl.drawRangeElements (gl.POINTS, 0, 1, 0, gl.UNSIGNED_BYTE, vertices);
this.expectError (gl.INVALID_OPERATION);
gl.bufferData (gl.ELEMENT_ARRAY_BUFFER, 32, gl.STATIC_DRAW);
gl.pauseTransformFeedback();
gl.drawRangeElements (gl.POINTS, 0, 1, 1, gl.UNSIGNED_BYTE, vertices);
gl.drawRangeElements (gl.POINTS, 0, 1, 0, gl.UNSIGNED_BYTE, vertices);
this.expectError (gl.NO_ERROR);
gl.endTransformFeedback ();
@ -796,7 +796,7 @@ goog.scope(function() {
gl.bufferData (gl.ELEMENT_ARRAY_BUFFER, 32, gl.STATIC_DRAW);
bufferedLogToConsole('gl.INVALID_OPERATION is generated if gl.useProgram(null) is set.');
gl.drawRangeElements(gl.POINTS, 0, 1, 1, gl.UNSIGNED_BYTE, vertices);
gl.drawRangeElements(gl.POINTS, 0, 1, 0, gl.UNSIGNED_BYTE, vertices);
this.expectError(gl.INVALID_OPERATION);
gl.deleteBuffer(bufElements);
@ -816,13 +816,13 @@ goog.scope(function() {
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, bufElements);
bufferedLogToConsole('gl.INVALID_ENUM is generated if mode is not an accepted value.');
gl.drawRangeElements(-1, 0, 1, 1, gl.UNSIGNED_BYTE, vertices);
gl.drawRangeElements(-1, 0, 1, 0, gl.UNSIGNED_BYTE, vertices);
this.expectError(gl.INVALID_ENUM);
bufferedLogToConsole('gl.INVALID_ENUM is generated if type is not one of the accepted values.');
gl.drawRangeElements(gl.TRIANGLES, 0, 1, 1, -1, vertices);
gl.drawRangeElements(gl.TRIANGLES, 0, 1, 0, -1, vertices);
this.expectError(gl.INVALID_ENUM);
gl.drawRangeElements(gl.TRIANGLES, 0, 1, 1, gl.FLOAT, vertices);
gl.drawRangeElements(gl.TRIANGLES, 0, 1, 0, gl.FLOAT, vertices);
this.expectError(gl.INVALID_ENUM);
bufferedLogToConsole('gl.INVALID_VALUE is generated if count is negative.');
@ -830,14 +830,14 @@ goog.scope(function() {
this.expectError(gl.INVALID_VALUE);
bufferedLogToConsole('gl.INVALID_VALUE is generated if end < start.');
gl.drawRangeElements(gl.TRIANGLES, 1, 0, 1, gl.UNSIGNED_BYTE, vertices);
gl.drawRangeElements(gl.TRIANGLES, 1, 0, 0, gl.UNSIGNED_BYTE, vertices);
this.expectError(gl.INVALID_VALUE);
bufferedLogToConsole('gl.INVALID_FRAMEBUFFER_OPERATION is generated if the currently bound framebuffer is not framebuffer complete.');
fbo = gl.createFramebuffer();
gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
gl.checkFramebufferStatus(gl.FRAMEBUFFER);
gl.drawRangeElements(gl.TRIANGLES, 0, 1, 1, gl.UNSIGNED_BYTE, vertices);
gl.drawRangeElements(gl.TRIANGLES, 0, 1, 0, gl.UNSIGNED_BYTE, vertices);
this.expectError(gl.INVALID_FRAMEBUFFER_OPERATION);
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
gl.deleteFramebuffer(fbo);
@ -859,13 +859,13 @@ goog.scope(function() {
gl.beginTransformFeedback (gl.TRIANGLES);
this.expectError (gl.NO_ERROR);
gl.drawRangeElements (gl.TRIANGLES, 0, 1, 1, gl.UNSIGNED_BYTE, vertices);
gl.drawRangeElements (gl.TRIANGLES, 0, 1, 0, gl.UNSIGNED_BYTE, vertices);
this.expectError (gl.INVALID_OPERATION);
gl.bufferData (gl.ELEMENT_ARRAY_BUFFER, 32, gl.STATIC_DRAW);
gl.pauseTransformFeedback();
gl.drawRangeElements (gl.TRIANGLES, 0, 1, 1, gl.UNSIGNED_BYTE, vertices);
gl.drawRangeElements (gl.TRIANGLES, 0, 1, 0, gl.UNSIGNED_BYTE, vertices);
this.expectError (gl.NO_ERROR);
gl.endTransformFeedback ();

Просмотреть файл

@ -38,6 +38,11 @@ var tcuMatrix = framework.common.tcuMatrix;
/** @const */ es3fShaderOperatorTests.MAX_INPUTS = 3;
let canvasWH = 256;
if (tcuTestCase.isQuickMode()) {
canvasWH = 32;
}
es3fShaderOperatorTests.stringJoin = function(elems, delim) {
var result = '';
for (var i = 0; i < elems.length; i++)
@ -2653,6 +2658,7 @@ es3fShaderOperatorTests.ShaderOperatorTests.prototype.init = function() {
// 8.3 Common Functions.
var comm = new es3fShaderOperatorTests.BuiltinFuncGroup("common_functions", "Common function tests.");
funcInfoGroups.push(comm);
comm.push(op("abs", "abs", GT, [v(GT, -2.0, 2.0)], f(0.5), f(0.5),
all, es3fShaderOperatorTests.unaryGenTypeFuncs(Math.abs)));
comm.push(op("sign", "sign", GT, [v(GT, -1.5, 1.5)], f(0.3), f(0.5),
@ -2663,6 +2669,10 @@ es3fShaderOperatorTests.ShaderOperatorTests.prototype.init = function() {
all, es3fShaderOperatorTests.unaryGenTypeFuncs(Math.trunc)));
comm.push(op("round", "round", GT, [v(GT, 2.5, 2.5)], f(0.2), f(0.7),
all, es3fShaderOperatorTests.unaryGenTypeFuncs(roundToEven)));
comm = new es3fShaderOperatorTests.BuiltinFuncGroup("common_functions", "Common function tests.");
funcInfoGroups.push(comm);
comm.push(op("roundEven", "roundEven", GT, [v(GT, 2.5, 2.5)], f(0.2), f(0.7),
all, es3fShaderOperatorTests.unaryGenTypeFuncs(roundToEven)));
comm.push(op("ceil", "ceil", GT, [v(GT, 2.5, 2.5)], f(0.2), f(0.5),
@ -2673,6 +2683,10 @@ es3fShaderOperatorTests.ShaderOperatorTests.prototype.init = function() {
mediumhighp, es3fShaderOperatorTests.binaryGenTypeFuncs(deMath.mod)));
comm.push(op("mod", "mod", GT, [v(FV, -2.0, 2.0), v(F, 0.9, 6.0)], f(0.5), f(0.5),
mediumhighp, es3fShaderOperatorTests.binaryVecScalarFuncs(deMath.modScale)));
comm = new es3fShaderOperatorTests.BuiltinFuncGroup("common_functions", "Common function tests.");
funcInfoGroups.push(comm);
comm.push(op("min", "min", GT, [v(GT, -1.0, 1.0), v(GT, -1.0, 1.0)], f(0.5), f(0.5),
all, es3fShaderOperatorTests.binaryGenTypeFuncs(Math.min)));
comm.push(op("min", "min", GT, [v(FV, -1.0, 1.0), v(F, -1.0, 1.0)], f(0.5), f(0.5),
@ -2686,6 +2700,10 @@ es3fShaderOperatorTests.ShaderOperatorTests.prototype.init = function() {
comm.push(op("min", "min", UGT, [v(UGT, 0.0, 8.0), v(UGT, 0.0, 8.0)], f(0.125), f(0.0),
all, es3fShaderOperatorTests.binaryGenTypeFuncs(Math.min, gluShaderUtil.DataType.INT,
gluShaderUtil.DataType.INT)));
comm = new es3fShaderOperatorTests.BuiltinFuncGroup("common_functions", "Common function tests.");
funcInfoGroups.push(comm);
comm.push(op("min", "min", UGT, [v(UV, 0.0, 8.0), v(U, 0.0, 8.0)], f(0.125), f(0.0),
all, es3fShaderOperatorTests.binaryVecScalarFuncs(minVecScalar, gluShaderUtil.DataType.UINT,
gluShaderUtil.DataType.UINT)));
@ -2699,6 +2717,10 @@ es3fShaderOperatorTests.ShaderOperatorTests.prototype.init = function() {
comm.push(op("max", "max", IGT, [v(IV, -4.0, 4.0), v(I, -4.0, 4.0)], f(0.125), f(0.5),
all, es3fShaderOperatorTests.binaryVecScalarFuncs(maxVecScalar, gluShaderUtil.DataType.INT,
gluShaderUtil.DataType.INT)));
comm = new es3fShaderOperatorTests.BuiltinFuncGroup("common_functions", "Common function tests.");
funcInfoGroups.push(comm);
comm.push(op("max", "max", UGT, [v(UGT, 0.0, 8.0), v(UGT, 0.0, 8.0)], f(0.125), f(0.0),
all, es3fShaderOperatorTests.binaryGenTypeFuncs(Math.max, gluShaderUtil.DataType.INT,
gluShaderUtil.DataType.INT)));
@ -2712,6 +2734,10 @@ es3fShaderOperatorTests.ShaderOperatorTests.prototype.init = function() {
comm.push(op("clamp", "clamp", IGT, [v(IGT, -4.0, 4.0), v(IGT, -2.0, 2.0), v(IGT, 2.0, 4.0)], f(0.125), f(0.5),
all, es3fShaderOperatorTests.ternaryGenTypeFuncs(deMath.clamp, gluShaderUtil.DataType.INT,
gluShaderUtil.DataType.INT)));
comm = new es3fShaderOperatorTests.BuiltinFuncGroup("common_functions", "Common function tests.");
funcInfoGroups.push(comm);
comm.push(op("clamp", "clamp", IGT, [v(IGT, -4.0, 4.0), v(I, -2.0, 2.0), v(I, 2.0, 4.0)], f(0.125), f(0.5),
all, es3fShaderOperatorTests.ternaryVecScalarScalarFuncs(clampVecScalarScalar, gluShaderUtil.DataType.INT,
gluShaderUtil.DataType.INT)));
@ -2725,6 +2751,10 @@ es3fShaderOperatorTests.ShaderOperatorTests.prototype.init = function() {
all, es3fShaderOperatorTests.ternaryGenTypeFuncs(mix)));
comm.push(op("mix", "mix", GT, [v(FV, -1.0, 1.0), v(FV, -1.0, 1.0), v(F, 0.0, 1.0)], f(0.5), f(0.5),
all, es3fShaderOperatorTests.ternaryVecVecScalarFuncs(mixVecVecScalar)));
comm = new es3fShaderOperatorTests.BuiltinFuncGroup("common_functions", "Common function tests.");
funcInfoGroups.push(comm);
comm.push(op("step", "step", GT, [v(GT, -1.0, 1.0), v(GT, -1.0, 0.0)], f(0.5), f(0.25),
all, es3fShaderOperatorTests.binaryGenTypeFuncs(step)));
comm.push(op("step", "step", GT, [v(F, -1.0, 1.0), v(FV, -1.0, 0.0)], f(0.5), f(0.25),
@ -2734,8 +2764,6 @@ es3fShaderOperatorTests.ShaderOperatorTests.prototype.init = function() {
comm.push(op("smoothstep", "smoothstep", GT, [v(F, -0.5, 0.0), v(F, 0.1, 1.0), v(FV, -1.0, 1.0)], f(0.5), f(0.5),
all, es3fShaderOperatorTests.ternaryScalarScalarVecFuncs(smoothStepScalarScalarVec)));
funcInfoGroups.push(comm);
// 8.4 Geometric Functions.
var geom = new es3fShaderOperatorTests.BuiltinFuncGroup("geometric", "Geometric function tests.");
geom.push(op("length", "length", F, [v(GT, -5.0, 5.0)], f(0.1), f(0.5),
@ -3196,6 +3224,11 @@ es3fShaderOperatorTests.ShaderOperatorTests.prototype.init = function() {
*/
es3fShaderOperatorTests.run = function(context, range) {
gl = context;
const canvas = gl.canvas;
canvas.width = canvasWH;
canvas.height = canvasWH;
//Set up Test Root parameters
var state = tcuTestCase.runner;
state.setRoot(new es3fShaderOperatorTests.ShaderOperatorTests());

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше