Backed out changeset 5ce1e3b69053 (bug 1724535) for causing webgl failures.

This commit is contained in:
Cosmin Sabou 2021-08-20 02:35:56 +03:00
Родитель ef6aad4afa
Коммит 18795ae59d
199 изменённых файлов: 1173 добавлений и 8190 удалений

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

@ -1 +1 @@
main master

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

@ -52,7 +52,12 @@ There is supposed to be an example drawing here, but it's not important.
componentSize: 4, componentSize: 4,
normalize: false, normalize: false,
}, },
{ data: new Uint16Array([ 0, 32767, 0, 32767, 0, 0, 0, 0, 0]), { data: new Float32Array([ 0, 1, 0, 1, 0, 0, 0, 0, 0 ]),
type: gl.FLOAT,
componentSize: 4,
normalize: false,
},
{ data: new Uint16Array([ 0, 32767, 0, 32767, 0, 0, 0, 0, 0 ]),
type: gl.SHORT, type: gl.SHORT,
componentSize: 2, componentSize: 2,
normalize: true, normalize: true,
@ -94,41 +99,6 @@ There is supposed to be an example drawing here, but it's not important.
} }
]; ];
if (wtu.getDefault3DContextVersion() >= 2) {
tests.push(...[
{ data: new Int32Array([ 0, 1, 0, 1, 0, 0, 0, 0, 0]),
type: gl.INT,
componentSize: 4,
normalize: false,
},
{ data: new Int32Array([ 0, 2147483647, 0, 2147483647, 0, 0, 0, 0, 0]),
type: gl.INT,
componentSize: 4,
normalize: true,
},
{ data: new Uint32Array([ 0, 1, 0, 1, 0, 0, 0, 0, 0]),
type: gl.UNSIGNED_INT,
componentSize: 4,
normalize: false,
},
{ data: new Uint32Array([ 0, 4294967295, 0, 4294967295, 0, 0, 0, 0, 0]),
type: gl.UNSIGNED_INT,
componentSize: 4,
normalize: true,
},
{ data: new Uint16Array([ 0, 0b11110000000000, 0, 0b11110000000000, 0, 0, 0, 0, 0]),
type: gl.HALF_FLOAT,
componentSize: 2,
normalize: false,
},
{ data: new Uint16Array([ 0, 0b11110000000000, 0, 0b11110000000000, 0, 0, 0, 0, 0]),
type: gl.HALF_FLOAT,
componentSize: 2,
normalize: false,
}
]);
}
var vertexObject = gl.createBuffer(); var vertexObject = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vertexObject); gl.bindBuffer(gl.ARRAY_BUFFER, vertexObject);
gl.bufferData(gl.ARRAY_BUFFER, 1024, gl.STATIC_DRAW); gl.bufferData(gl.ARRAY_BUFFER, 1024, gl.STATIC_DRAW);

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

@ -67,10 +67,10 @@ if (!gl) {
gl.vertexAttribPointer(0, 1, gl.UNSIGNED_INT, 0, 0, 0); gl.vertexAttribPointer(0, 1, gl.UNSIGNED_INT, 0, 0, 0);
wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, wtu.glErrorShouldBe(gl, gl.INVALID_ENUM,
"vertexAttribPointer should not support UNSIGNED_INT"); "vertexAttribPointer should not support UNSIGNED_INT");
}
gl.vertexAttribPointer(0, 1, gl.FIXED, 0, 0, 0); gl.vertexAttribPointer(0, 1, gl.FIXED, 0, 0, 0);
wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, wtu.glErrorShouldBe(gl, gl.INVALID_ENUM,
"vertexAttribPointer should not support FIXED"); "vertexAttribPointer should not support FIXED");
}
var checkVertexAttribPointer = function( var checkVertexAttribPointer = function(
gl, err, reason, size, type, normalize, stride, offset) { gl, err, reason, size, type, normalize, stride, offset) {
@ -100,16 +100,6 @@ if (!gl) {
{ type:gl.FLOAT, bytesPerComponent: 4 }, { type:gl.FLOAT, bytesPerComponent: 4 },
]; ];
if (wtu.getDefault3DContextVersion() >= 2) {
types.push(...[
{ type:gl.INT, bytesPerComponent: 4 },
{ type:gl.UNSIGNED_INT, bytesPerComponent: 4 },
{ type:gl.HALF_FLOAT, bytesPerComponent: 2 },
{ type:gl.INT_2_10_10_10_REV, bytesPerComponent: 4, minSize: 4 },
{ type:gl.UNSIGNED_INT_2_10_10_10_REV, bytesPerComponent: 4, minSize: 4 },
]);
}
for (var ii = 0; ii < types.length; ++ii) { for (var ii = 0; ii < types.length; ++ii) {
var info = types[ii]; var info = types[ii];
debug(""); debug("");
@ -138,10 +128,6 @@ if (!gl) {
reason = "because stride is bad"; reason = "because stride is bad";
err = gl.INVALID_OPERATION; err = gl.INVALID_OPERATION;
} }
if (size < info.minSize) {
reason = "because size < minSize";
err = gl.INVALID_OPERATION;
}
checkVertexAttribPointer( checkVertexAttribPointer(
gl, err, reason, size, info.type, false, stride, offset); gl, err, reason, size, info.type, false, stride, offset);
} }
@ -149,10 +135,10 @@ if (!gl) {
if (offset == 0) { if (offset == 0) {
checkVertexAttribPointer( checkVertexAttribPointer(
gl, size < info.minSize ? gl.INVALID_OPERATION : gl.NO_ERROR, "at stride limit", gl, gl.NO_ERROR, "at stride limit",
size, info.type, false, stride, offset); size, info.type, false, stride, offset);
checkVertexAttribPointer( checkVertexAttribPointer(
gl, size < info.minSize ? [gl.INVALID_OPERATION, gl.INVALID_VALUE] : gl.INVALID_VALUE, "over stride limit", gl, gl.INVALID_VALUE, "over stride limit",
size, info.type, false, size, info.type, false,
stride + info.bytesPerComponent, offset); stride + info.bytesPerComponent, offset);
} }

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

@ -94,24 +94,15 @@ function bufferDataSizesTest() {
{ parameter: new ArrayBuffer(0), expectedBufferSize: 0 }, { parameter: new ArrayBuffer(0), expectedBufferSize: 0 },
{ parameter: new ArrayBuffer(4), expectedBufferSize: 4 }, { parameter: new ArrayBuffer(4), expectedBufferSize: 4 },
{ parameter: new Uint8Array(new ArrayBuffer(5)), expectedBufferSize: 5 },
{ parameter: new DataView(new ArrayBuffer(7)), expectedBufferSize: 7 },
{ parameter: "WebGL Rocks!", expectedBufferSize: 0 }, { parameter: "WebGL Rocks!", expectedBufferSize: 0 },
{ parameter: { mystring: "WebGL Rocks!" }, expectedBufferSize: 0 }, { parameter: { mystring: "WebGL Rocks!" }, expectedBufferSize: 0 },
]; ];
if (window.SharedArrayBuffer) {
bufferDataParams.push(
{ parameter: new SharedArrayBuffer(3), expectedBufferSize: 3 },
{ parameter: new Uint8Array(new SharedArrayBuffer(6)), expectedBufferSize: 6 },
{ parameter: new DataView(new SharedArrayBuffer(8)), expectedBufferSize: 8 }
);
}
bufferDataParams.forEach(function (bufferDataParam) { bufferDataParams.forEach(function (bufferDataParam) {
var buffer = gl.createBuffer(); var buffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, buffer); gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
gl.bufferData(gl.ARRAY_BUFFER, bufferDataParam.parameter, gl.STATIC_DRAW); gl.bufferData(gl.ARRAY_BUFFER, bufferDataParam.parameter, gl.STATIC_DRAW);
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Passing " + bufferDataParam.parameter + " to bufferData"); wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Passing " + bufferDataParam.parameter + " to bufferData");
@ -163,18 +154,6 @@ function bufferSubDataTest() {
shouldThrow("gl.bufferSubData(gl.ARRAY_BUFFER, 0, { mynumber: 42});"); shouldThrow("gl.bufferSubData(gl.ARRAY_BUFFER, 0, { mynumber: 42});");
shouldThrow("gl.bufferSubData(gl.ARRAY_BUFFER, 10, null)"); shouldThrow("gl.bufferSubData(gl.ARRAY_BUFFER, 10, null)");
shouldThrow("gl.bufferSubData(gl.ARRAY_BUFFER, 10, undefined)"); shouldThrow("gl.bufferSubData(gl.ARRAY_BUFFER, 10, undefined)");
if (window.SharedArrayBuffer) {
const validDatas = [
'new SharedArrayBuffer(3)',
'new Uint8Array(new SharedArrayBuffer(3))',
'new DataView(new SharedArrayBuffer(3))',
];
for (const x of validDatas) {
shouldNotThrow(`gl.bufferSubData(gl.ARRAY_BUFFER, 0, ${x})`);
}
}
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should generate no GL error"); wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should generate no GL error");
// - // -

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

@ -13,7 +13,6 @@ drawingbuffer-test.html
--min-version 1.0.4 render-after-resize-test.html --min-version 1.0.4 render-after-resize-test.html
--min-version 1.0.2 texture-bindings-unaffected-on-resize.html --min-version 1.0.2 texture-bindings-unaffected-on-resize.html
--min-version 1.0.2 to-data-url-test.html --min-version 1.0.2 to-data-url-test.html
--min-version 1.0.4 to-data-url-after-composite.html
viewport-unchanged-upon-resize.html viewport-unchanged-upon-resize.html
--min-version 1.0.4 webgl-to-2d-canvas.html --min-version 1.0.4 webgl-to-2d-canvas.html

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

@ -36,6 +36,10 @@ const SMALL = 2;
// different results. Sometimes wrong, sometimes correct. // different results. Sometimes wrong, sometimes correct.
const LARGE = 1200; const LARGE = 1200;
function render() {
}
gl.uniform4fv(colorLocation, [0.0, 1.0, 0.0, 1.0]); gl.uniform4fv(colorLocation, [0.0, 1.0, 0.0, 1.0]);
// - // -
@ -60,19 +64,6 @@ wtu.drawUnitQuad(gl);
wtu.checkCanvasRect(gl, 0, 0, 1, 1, [ 0, 255, 0, 255 ]); wtu.checkCanvasRect(gl, 0, 0, 1, 1, [ 0, 255, 0, 255 ]);
debug('\nCause a GL error, then resize and render.');
gl.depthFunc(0); // Causes INVALID_ENUM
gl.canvas.width = gl.canvas.height = LARGE;
gl.clear(gl.COLOR_BUFFER_BIT);
gl.canvas.width = gl.canvas.height = SMALL;
gl.clear(gl.COLOR_BUFFER_BIT);
wtu.drawUnitQuad(gl);
wtu.checkCanvasRect(gl, 0, 0, 1, 1, [ 0, 255, 0, 255 ]);
wtu.glErrorShouldBe(gl, gl.INVALID_ENUM);
wtu.glErrorShouldBe(gl, gl.NO_ERROR);
// - // -
debug('\nRender, no-op resize, then depth-fail render.'); debug('\nRender, no-op resize, then depth-fail render.');

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

@ -1,51 +0,0 @@
<!--
Copyright (c) 2021 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">
<title>WebGL toDataURL after composite 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 width="20" height="20" style="border: 1px solid black; width: 128px; height: 128px" id="c3d"></canvas>
<canvas width="20" height="20" style="border: 1px solid black; width: 128px; height: 128px" id="c2d"></canvas>
<div id="description"></div>
<div id="console"></div>
<script type="application/javascript">
const wtu = WebGLTestUtils;
let gl;
let ctx;
function main() {
description();
const c2d = document.getElementById("c2d");
ctx = c2d.getContext("2d");
gl = wtu.create3DContext("c3d", { preserveDrawingBuffer: true });
// Clear to green
gl.clearColor(0.0, 1.0, 0.0, 1.0);
gl.clear(gl.COLOR_BUFFER_BIT);
wtu.waitForComposite(() => {
// Performs gl.canvas.toDataURL() internally
let img = wtu.makeImageFromCanvas(gl.canvas, function() {
ctx.drawImage(img, 0, 0);
wtu.checkCanvas(ctx, [0, 255, 0], "toDataURL loaded into image, drawn into 2D context, should be green", 5);
finishTest();
});
});
};
main();
var successfullyParsed = true;
</script>
</body>
</html>

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

@ -26,53 +26,24 @@ var ctx;
var main = function() { var main = function() {
description(); description();
ctx = document.getElementById("c2d").getContext("2d"); ctx = document.getElementById("c2d").getContext("2d");
gl = wtu.create3DContext("c3d");
var updateCanvas = function(width, height, attributes) {
var canvas = document.getElementById("c3d");
if (gl && (gl.attributes !== attributes)) {
// Attributes changed, recreate the canvas
var newCanvas = canvas.cloneNode();
canvas.parentNode.replaceChild(newCanvas, canvas);
canvas = newCanvas;
gl = undefined;
}
canvas.width = width;
canvas.height = height;
if (!gl) {
gl = wtu.create3DContext(canvas, attributes);
if (!gl) { if (!gl) {
testFailed("can't create 3d context"); testFailed("can't create 3d context");
finishTest();
return; return;
} }
gl.attributes = attributes;
}
return gl;
};
var clearRect = function(gl, x, y, width, height, color) { var clearRect = function(gl, x, y, width, height, color) {
gl.clearColor(color[0] / 255, color[1] / 255, color[2] / 255, color[3] / 255); gl.clearColor(color[0] / 255, color[1] / 255, color[2] / 255, color[3] / 255);
gl.scissor(x, y, width, height); gl.scissor(x, y, width, height);
gl.clear(gl.COLOR_BUFFER_BIT); gl.clear(gl.COLOR_BUFFER_BIT);
}; };
var testSize = function(width, height, attributes, callback) { var testSize = function(gl, width, height, callback) {
let attributesDebugMessage = ""; debug("testing " + width + " by " + height);
if (attributes) { gl.canvas.width = width;
attributesDebugMessage = " attributes: " + JSON.stringify(attributes); gl.canvas.height = height;
}
debug("testing " + width + " by " + height + attributesDebugMessage);
var gl = updateCanvas(width, height, attributes);
if (!gl) {
callback();
return;
}
gl.viewport(0, 0, width, height); gl.viewport(0, 0, width, height);
gl.enable(gl.SCISSOR_TEST); gl.enable(gl.SCISSOR_TEST);
@ -100,9 +71,6 @@ var main = function() {
}); });
}; };
const premultipliedAlphaAttributes = {
premultipliedAlpha: false,
};
var tests = [ var tests = [
{ width: 16 , height: 16 , }, { width: 16 , height: 16 , },
{ width: 16 - 1, height: 16 , }, { width: 16 - 1, height: 16 , },
@ -119,7 +87,6 @@ var main = function() {
{ width: 512 - 1, height: 512 - 1, }, { width: 512 - 1, height: 512 - 1, },
{ width: 512 + 1, height: 512 - 1, }, { width: 512 + 1, height: 512 - 1, },
{ width: 512 - 1, height: 512 + 1, }, { width: 512 - 1, height: 512 + 1, },
{ width: 16 , height: 16 , attributes: premultipliedAlphaAttributes},
]; ];
var testIndex = 0; var testIndex = 0;
var runNextTest = function() { var runNextTest = function() {
@ -128,7 +95,7 @@ var main = function() {
return; return;
} }
var test = tests[testIndex++]; var test = tests[testIndex++];
testSize(test.width, test.height, test.attributes, function() { testSize(gl, test.width, test.height, function() {
setTimeout(runNextTest, 0); setTimeout(runNextTest, 0);
}) })
}; };

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

@ -12,7 +12,6 @@ context-attributes-alpha-depth-stencil-antialias.html
context-lost-restored.html context-lost-restored.html
context-lost.html context-lost.html
--max-version 1.9.9 context-type-test.html --max-version 1.9.9 context-type-test.html
--min-version 1.0.4 deleted-object-behavior.html
incorrect-context-object-behaviour.html incorrect-context-object-behaviour.html
--max-version 1.9.9 methods.html --max-version 1.9.9 methods.html
premultiplyalpha-test.html premultiplyalpha-test.html

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

@ -17,13 +17,13 @@ found in the LICENSE.txt file.
display: inline-block; display: inline-block;
} }
canvas { canvas {
width:10px; width:50px;
height:10px; height:50px;
} }
.square { .square {
display:inline-block; display:inline-block;
width:10px; width:50px;
height:10px; height:50px;
background-color:red; background-color:red;
} }
</style> </style>

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

@ -11,7 +11,6 @@ found in the LICENSE.txt file.
<link rel="stylesheet" href="../../resources/js-test-style.css"/> <link rel="stylesheet" href="../../resources/js-test-style.css"/>
<script src="../../js/js-test-pre.js"></script> <script src="../../js/js-test-pre.js"></script>
<script src="../../js/webgl-test-utils.js"></script> <script src="../../js/webgl-test-utils.js"></script>
<script src="../../js/tests/context-methods.js"></script>
</head> </head>
<body> <body>
<div id="description"></div> <div id="description"></div>
@ -21,7 +20,7 @@ found in the LICENSE.txt file.
"use strict"; "use strict";
description("This test ensures that the WebGL context has all the methods in the specification."); description("This test ensures that the WebGL context has all the methods in the specification.");
const methods = [ var methods = [
"getContextAttributes", "getContextAttributes",
"activeTexture", "activeTexture",
"attachShader", "attachShader",
@ -160,14 +159,55 @@ const methods = [
"viewport" "viewport"
]; ];
// Properties to be ignored because they were added in versions of the
// spec that are backward-compatible with this version
var ignoredMethods = [
// There is no official spec for the commit API yet, the proposal link is:
// https://wiki.whatwg.org/wiki/OffscreenCanvas
"commit"
];
function assertFunction(v, f) {
try {
if (typeof v[f] != "function") {
testFailed("Property either does not exist or is not a function: " + f);
return false;
} else {
return true;
}
} catch(e) {
testFailed("Trying to access the property '" + f + "' threw an error: "+e.toString());
}
}
debug(""); debug("");
debug("Canvas.getContext"); debug("Canvas.getContext");
const wtu = WebGLTestUtils; var wtu = WebGLTestUtils;
const canvas = document.getElementById("canvas"); var canvas = document.getElementById("canvas");
const gl = wtu.create3DContext(canvas); var gl = wtu.create3DContext(canvas);
var passed = true;
for (var i=0; i<methods.length; i++) {
var r = assertFunction(gl, methods[i]);
passed = passed && r;
}
if (passed) {
testPassed("All WebGL methods found.");
}
var extended = false;
for (var i in gl) {
if (typeof gl[i] == "function" && methods.indexOf(i) == -1 && ignoredMethods.indexOf(i) == -1) {
if (!extended) {
extended = true;
testFailed("Also found the following extra methods:");
}
testFailed(i);
}
}
testContextMethods(gl, methods); if (!extended) {
testPassed("No extra methods found on WebGL context.");
}
debug(""); debug("");
var successfullyParsed = true; var successfullyParsed = true;

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

@ -1,7 +1,6 @@
--min-version 1.0.3 --max-version 1.9.9 angle-instanced-arrays.html --min-version 1.0.3 --max-version 1.9.9 angle-instanced-arrays.html
--min-version 1.0.3 --max-version 1.9.9 angle-instanced-arrays-out-of-bounds.html --min-version 1.0.3 --max-version 1.9.9 angle-instanced-arrays-out-of-bounds.html
--min-version 1.0.3 --max-version 1.9.9 ext-blend-minmax.html --min-version 1.0.3 --max-version 1.9.9 ext-blend-minmax.html
--min-version 1.0.4 ext-color-buffer-half-float.html
--min-version 1.0.4 ext-float-blend.html --min-version 1.0.4 ext-float-blend.html
--min-version 1.0.4 ext-texture-compression-bptc.html --min-version 1.0.4 ext-texture-compression-bptc.html
--min-version 1.0.4 ext-texture-compression-rgtc.html --min-version 1.0.4 ext-texture-compression-rgtc.html
@ -11,7 +10,6 @@
--min-version 1.0.3 --max-version 1.9.9 ext-sRGB.html --min-version 1.0.3 --max-version 1.9.9 ext-sRGB.html
--min-version 1.0.2 ext-texture-filter-anisotropic.html --min-version 1.0.2 ext-texture-filter-anisotropic.html
--min-version 1.0.2 get-extension.html --min-version 1.0.2 get-extension.html
--min-version 1.0.4 khr-parallel-shader-compile.html
--max-version 1.9.9 oes-standard-derivatives.html --max-version 1.9.9 oes-standard-derivatives.html
--max-version 1.9.9 oes-texture-float-with-canvas.html --max-version 1.9.9 oes-texture-float-with-canvas.html
--max-version 1.9.9 oes-texture-float-with-image-data.html --max-version 1.9.9 oes-texture-float-with-image-data.html
@ -35,7 +33,7 @@ webgl-debug-shaders.html
--min-version 1.0.4 webgl-compressed-texture-etc.html --min-version 1.0.4 webgl-compressed-texture-etc.html
--min-version 1.0.4 webgl-compressed-texture-etc1.html --min-version 1.0.4 webgl-compressed-texture-etc1.html
--min-version 1.0.3 webgl-compressed-texture-pvrtc.html --min-version 1.0.3 webgl-compressed-texture-pvrtc.html
--min-version 1.0.4 s3tc-and-rgtc.html --min-version 1.0.2 webgl-compressed-texture-s3tc.html
--min-version 1.0.4 webgl-compressed-texture-s3tc-srgb.html --min-version 1.0.4 webgl-compressed-texture-s3tc-srgb.html
--min-version 1.0.3 webgl-compressed-texture-size-limit.html --min-version 1.0.3 webgl-compressed-texture-size-limit.html
--min-version 1.0.2 --max-version 1.9.9 webgl-depth-texture.html --min-version 1.0.2 --max-version 1.9.9 webgl-depth-texture.html

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

@ -196,9 +196,6 @@ function runOutputTests() {
0.0, 1.0, 0.0, 1.0, // Green 0.0, 1.0, 0.0, 1.0, // Green
0.0, 0.0, 1.0, 1.0, // Blue 0.0, 0.0, 1.0, 1.0, // Blue
1.0, 1.0, 0.0, 1.0, // Yellow 1.0, 1.0, 0.0, 1.0, // Yellow
// extra data when colorLoc divisor is set back to 0
1.0, 1.0, 0.0, 1.0, // Yellow
1.0, 1.0, 0.0, 1.0, // Yellow
]); ]);
var colorBuffer = gl.createBuffer(); var colorBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer); gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer);
@ -280,19 +277,6 @@ function runOutputTests() {
wtu.checkCanvasRect(gl, Math.ceil(0.25*canvas.width), 0, w, h, [0, 0, 255, 255]); wtu.checkCanvasRect(gl, Math.ceil(0.25*canvas.width), 0, w, h, [0, 0, 255, 255]);
wtu.checkCanvasRect(gl, Math.ceil(0.75*canvas.width), 0, w, h, [255, 255, 0, 255]); wtu.checkCanvasRect(gl, Math.ceil(0.75*canvas.width), 0, w, h, [255, 255, 0, 255]);
debug("");
debug("Testing drawArraysInstancedANGLE with attributes 'divisor' reset to 0");
debug("Correct rendering output: 4 yellow triangles");
debug("Possible incorrect rendering output: missing triangles, or triangles with different color at each vertex");
ext.vertexAttribDivisorANGLE(colorLoc, 0);
gl.clear(gl.COLOR_BUFFER_BIT);
ext.drawArraysInstancedANGLE(gl.TRIANGLES, 3, 3, instanceCount);
wtu.checkCanvasRect(gl, Math.ceil(0.25*canvas.width), 0.5*canvas.height, w, h, [255, 255, 0, 255]);
wtu.checkCanvasRect(gl, Math.ceil(0.75*canvas.width), 0.5*canvas.height, w, h, [255, 255, 0, 255]);
wtu.checkCanvasRect(gl, Math.ceil(0.25*canvas.width), 0, w, h, [255, 255, 0, 255]);
wtu.checkCanvasRect(gl, Math.ceil(0.75*canvas.width), 0, w, h, [255, 255, 0, 255]);
ext.vertexAttribDivisorANGLE(colorLoc, 1);
wtu.setupUnitQuad(gl, 0); wtu.setupUnitQuad(gl, 0);
wtu.setupIndexedQuad(gl, 1, 0); wtu.setupIndexedQuad(gl, 1, 0);
gl.bindBuffer(gl.ARRAY_BUFFER, offsetBuffer); gl.bindBuffer(gl.ARRAY_BUFFER, offsetBuffer);

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

@ -1,27 +0,0 @@
<!--
Copyright (c) 2020 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">
<title>WebGL EXT_color_buffer_half_float Conformance Tests</title>
<link rel="stylesheet" href="../../resources/js-test-style.css"/>
<script src="../../js/js-test-pre.js"></script>
<script src="../../js/webgl-test-utils.js"></script>
</head> 
<body>
<div id="description"></div>
<canvas id="canvas" style="width: 50px; height: 50px;"> </canvas>
<div id="console"></div>
<script>
var version = 1;
</script>
<script src="../../js/tests/ext-color-buffer-half-float.js"></script>
<script src="../../js/js-test-post.js"></script>
</body>
</html>

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

@ -60,7 +60,7 @@ function runTestExtension() {
// * <height> is not a multiple of four, and <height> plus <yoffset> is // * <height> is not a multiple of four, and <height> plus <yoffset> is
// not equal to TEXTURE_HEIGHT; or // not equal to TEXTURE_HEIGHT; or
// * <xoffset> or <yoffset> is not a multiple of four. // * <xoffset> or <yoffset> is not a multiple of four.
ctu.testTexSubImageDimensions(gl, ext, validFormats, expectedByteLength, getBlockDimensions, ctu.testTexSubImageDimensions(gl, validFormats, expectedByteLength, getBlockDimensions,
16, 16, [ 16, 16, [
{ xoffset: 0, yoffset: 0, width: 4, height: 3, { xoffset: 0, yoffset: 0, width: 4, height: 3,
expectation: gl.INVALID_OPERATION, message: "height is not a multiple of 4" }, expectation: gl.INVALID_OPERATION, message: "height is not a multiple of 4" },
@ -73,63 +73,6 @@ function runTestExtension() {
{ xoffset: 12, yoffset: 12, width: 4, height: 4, { xoffset: 12, yoffset: 12, width: 4, height: 4,
expectation: gl.NO_ERROR, message: "is valid" }, expectation: gl.NO_ERROR, message: "is valid" },
]); ]);
// Test TexImage validation on level dimensions combinations.
// When level equals 0, width and height must be a multiple of 4.
// When level is larger than 0, this constraint doesn't apply.
let npotExpectation, npotMessage;
if (contextVersion >= 2) {
npotExpectation = gl.NO_ERROR;
npotMessage = "valid";
} else {
npotExpectation = gl.INVALID_VALUE;
npotMessage = "invalid";
}
ctu.testTexImageLevelDimensions(gl, ext, validFormats, expectedByteLength, getBlockDimensions,
[
{ level: 0, width: 4, height: 3,
expectation: gl.INVALID_OPERATION, message: "level is 0, height is not a multiple of 4" },
{ level: 0, width: 3, height: 4,
expectation: gl.INVALID_OPERATION, message: "level is 0, width is not a multiple of 4" },
{ level: 0, width: 2, height: 2,
expectation: gl.INVALID_OPERATION, message: "level is 0, width is not a multiple of 4" },
{ level: 0, width: 4, height: 4,
expectation: gl.NO_ERROR, message: "is valid" },
{ level: 1, width: 1, height: 1,
expectation: gl.INVALID_OPERATION, message: "implied base mip 2x2 is invalid" },
{ level: 1, width: 1, height: 2,
expectation: gl.INVALID_OPERATION, message: "implied base mip 2x4 is invalid" },
{ level: 1, width: 2, height: 1,
expectation: gl.INVALID_OPERATION, message: "implied base mip 4x2 is invalid" },
{ level: 1, width: 2, height: 2,
expectation: gl.NO_ERROR, message: "implied base mip 4x4 is valid" },
{ level: 2, width: 1, height: 3,
expectation: npotExpectation, message: "implied base mip 4x12 is " + npotMessage },
]);
// Test that BPTC enums are not accepted by texImage2D
{
var tex = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, tex);
gl.texImage2D(gl.TEXTURE_2D, 0, ext.COMPRESSED_RGBA_BPTC_UNORM_EXT, 4, 4, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "COMPRESSED_RGBA_BPTC_UNORM_EXT fails with texImage2D");
gl.texImage2D(gl.TEXTURE_2D, 0, ext.COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT, 4, 4, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT fails with texImage2D");
if (contextVersion >= 2) {
gl.texImage2D(gl.TEXTURE_2D, 0, ext.COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT, 4, 4, 0, gl.RGB, gl.FLOAT, null);
wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT fails with texImage2D");
gl.texImage2D(gl.TEXTURE_2D, 0, ext.COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT, 4, 4, 0, gl.RGB, gl.FLOAT, null);
wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT fails with texImage2D");
}
gl.deleteTexture(tex);
}
}; };
function runTest() { function runTest() {

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

@ -65,7 +65,7 @@ function runTestExtension() {
// * <height> is not a multiple of four, and <height> plus <yoffset> is // * <height> is not a multiple of four, and <height> plus <yoffset> is
// not equal to TEXTURE_HEIGHT; or // not equal to TEXTURE_HEIGHT; or
// * <xoffset> or <yoffset> is not a multiple of four. // * <xoffset> or <yoffset> is not a multiple of four.
ctu.testTexSubImageDimensions(gl, ext, validFormats, expectedByteLength, getBlockDimensions, ctu.testTexSubImageDimensions(gl, validFormats, expectedByteLength, getBlockDimensions,
16, 16, [ 16, 16, [
{ xoffset: 0, yoffset: 0, width: 4, height: 3, { xoffset: 0, yoffset: 0, width: 4, height: 3,
expectation: gl.INVALID_OPERATION, message: "height is not a multiple of 4" }, expectation: gl.INVALID_OPERATION, message: "height is not a multiple of 4" },
@ -78,61 +78,6 @@ function runTestExtension() {
{ xoffset: 12, yoffset: 12, width: 4, height: 4, { xoffset: 12, yoffset: 12, width: 4, height: 4,
expectation: gl.NO_ERROR, message: "is valid" }, expectation: gl.NO_ERROR, message: "is valid" },
]); ]);
// Test TexImage validation on level dimensions combinations.
// When level equals 0, width and height must be a multiple of 4.
// When level is larger than 0, this constraint doesn't apply.
let npotExpectation, npotMessage;
if (contextVersion >= 2) {
npotExpectation = gl.NO_ERROR;
npotMessage = "valid";
} else {
npotExpectation = gl.INVALID_VALUE;
npotMessage = "invalid";
}
ctu.testTexImageLevelDimensions(gl, ext, validFormats, expectedByteLength, getBlockDimensions,
[
{ level: 0, width: 4, height: 3,
expectation: gl.INVALID_OPERATION, message: "level is 0, height is not a multiple of 4" },
{ level: 0, width: 3, height: 4,
expectation: gl.INVALID_OPERATION, message: "level is 0, width is not a multiple of 4" },
{ level: 0, width: 2, height: 2,
expectation: gl.INVALID_OPERATION, message: "level is 0, width is not a multiple of 4" },
{ level: 0, width: 4, height: 4,
expectation: gl.NO_ERROR, message: "is valid" },
{ level: 1, width: 1, height: 1,
expectation: gl.INVALID_OPERATION, message: "implied base mip 2x2 is invalid" },
{ level: 1, width: 1, height: 2,
expectation: gl.INVALID_OPERATION, message: "implied base mip 2x4 is invalid" },
{ level: 1, width: 2, height: 1,
expectation: gl.INVALID_OPERATION, message: "implied base mip 4x2 is invalid" },
{ level: 1, width: 2, height: 2,
expectation: gl.NO_ERROR, message: "implied base mip 4x4 is valid" },
{ level: 2, width: 1, height: 3,
expectation: npotExpectation, message: "implied base mip 4x12 is " + npotMessage },
]);
// Test that RGTC enums are not accepted by texImage2D
if (contextVersion >= 2) {
var tex = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, tex);
gl.texImage2D(gl.TEXTURE_2D, 0, ext.COMPRESSED_RED_RGTC1_EXT, 4, 4, 0, gl.RED, gl.UNSIGNED_BYTE, null);
wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "COMPRESSED_RED_RGTC1_EXT fails with texImage2D");
gl.texImage2D(gl.TEXTURE_2D, 0, ext.COMPRESSED_SIGNED_RED_RGTC1_EXT, 4, 4, 0, gl.RED, gl.BYTE, null);
wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "COMPRESSED_SIGNED_RED_RGTC1_EXT fails with texImage2D");
gl.texImage2D(gl.TEXTURE_2D, 0, ext.COMPRESSED_RED_GREEN_RGTC2_EXT, 4, 4, 0, gl.RG, gl.UNSIGNED_BYTE, null);
wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "COMPRESSED_RED_GREEN_RGTC2_EXT fails with texImage2D");
gl.texImage2D(gl.TEXTURE_2D, 0, ext.COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT, 4, 4, 0, gl.RG, gl.BYTE, null);
wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT fails with texImage2D");
gl.deleteTexture(tex);
}
}; };
function runTest() { function runTest() {

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

@ -1,220 +0,0 @@
<!--
Copyright (c) 2020 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>
<style>
.spinner {
width: 100px;
height: 100px;
border: 20px solid transparent;
border-top: 20px solid black;
border-radius: 100%;
text-align: center;
padding: 10px;
}
@keyframes rotation {
from { transorm: rotate(0); }
to { transform: rotate(360deg); }
}
</style>
</head>
<body>
<div id="description"></div>
<button onclick='compileShaders()'>The spinners below should not stutter when you click this button.</button>
<div class="spinner" style="animation: rotation 2s infinite linear;">CSS</div>
<div class="spinner" id=spinner>JS</div>
<div id="console"></div>
<canvas id=canvas></canvas>
<script>
"use strict";
description("Test KHR_parallel_shader_compile");
function spinSpinner() {
let degrees = (performance.now() / 1000 / 2 % 1.) * 360;
spinner.style.transform = `rotate(${degrees}deg)`;
requestAnimationFrame(spinSpinner);
}
spinSpinner();
const wtu = WebGLTestUtils;
const gl = wtu.create3DContext();
const loseContext = wtu.getExtensionWithKnownPrefixes(gl, "WEBGL_lose_context");
let counter = 0;
const vertexSource = (extra) => `
void main() {
vec4 result = vec4(0.${counter++});
${extra || ''}
gl_Position = result;
}`;
const fragmentSource = (extra) => `
precision highp float;
void main() {
vec4 result = vec4(0.${counter++});
${extra || ''}
gl_FragColor = result;
}`;
let vs = gl.createShader(gl.VERTEX_SHADER);
let fs = gl.createShader(gl.FRAGMENT_SHADER);
let program = gl.createProgram();
gl.attachShader(program, vs);
gl.attachShader(program, fs);
const COMPLETION_STATUS_KHR = 0x91B1;
gl.shaderSource(vs, vertexSource());
gl.compileShader(vs);
let status = gl.getShaderParameter(vs, COMPLETION_STATUS_KHR);
if (status !== null) testFailed('Extension disabled, status should be null');
wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, "extension disabled");
gl.shaderSource(fs, fragmentSource());
gl.compileShader(fs);
gl.linkProgram(program);
status = gl.getProgramParameter(program, COMPLETION_STATUS_KHR);
if (status !== null) testFailed('Extension disabled, status should be null');
wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, "extension disabled");
const ext = wtu.getExtensionWithKnownPrefixes(gl, "KHR_parallel_shader_compile");
let successfullyParsed = false;
let extraCode = '';
(async () => {
if (!ext) {
testPassed("No KHR_parallel_shader_compile support -- this is legal");
} else {
testPassed("Successfully enabled KHR_parallel_shader_compile extension");
shouldBe("ext.COMPLETION_STATUS_KHR", "0x91B1");
debug("Checking that status is a boolean.");
gl.shaderSource(vs, vertexSource());
gl.compileShader(vs);
let status = gl.getShaderParameter(vs, COMPLETION_STATUS_KHR);
if (status !== true && status !== false) testFailed("status should be a boolean");
gl.linkProgram(program);
status = gl.getProgramParameter(program, COMPLETION_STATUS_KHR);
if (status !== true && status !== false) testFailed("status should be a boolean");
const minimumShaderCompileDurationMs = 500;
debug(`Constructing shader that takes > ${minimumShaderCompileDurationMs} ms to compile.`);
let measuredCompileDuration = 0;
extraCode = '\n if (true) { result += vec4(0.0000001); }';
for (let i = 0; measuredCompileDuration < minimumShaderCompileDurationMs; i++) {
extraCode += extraCode;
extraCode += extraCode;
if (i < 4) continue;
gl.shaderSource(vs, vertexSource(extraCode));
gl.shaderSource(fs, fragmentSource(extraCode));
gl.compileShader(vs);
gl.compileShader(fs);
gl.linkProgram(program);
const start = performance.now();
if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
testFailed(`Shaders failed to compile.
program: ${gl.getProgramInfoLog(program)}
vs: ${gl.getShaderInfoLog(vs)}
fs: ${gl.getShaderInfoLog(fs)}`);
break;
}
measuredCompileDuration = performance.now() - start;
}
debug('');
gl.shaderSource(vs, vertexSource(extraCode));
gl.shaderSource(fs, fragmentSource(extraCode));
gl.compileShader(vs);
gl.compileShader(fs);
gl.linkProgram(program);
let start = performance.now();
gl.getShaderParameter(fs, COMPLETION_STATUS_KHR);
gl.getShaderParameter(vs, COMPLETION_STATUS_KHR);
let duration = performance.now() - start;
if (duration > 100)
testFailed(`Querying shader status should not wait for compilation. Took ${duration} ms`);
let frames = 0;
const maximumTimeToWait = measuredCompileDuration * 4;
while (!gl.getProgramParameter(program, COMPLETION_STATUS_KHR)
&& performance.now() - start < maximumTimeToWait) {
frames++;
await new Promise(requestAnimationFrame);
}
duration = performance.now() - start;
if (!gl.getProgramParameter(program, COMPLETION_STATUS_KHR)) {
testFailed(`Program took longer than ${maximumTimeToWait} ms to compile. Expected: ${measuredCompileDuration} ms, actual: ${duration} ms`);
} else if (!gl.getShaderParameter(vs, COMPLETION_STATUS_KHR) || !gl.getShaderParameter(fs, COMPLETION_STATUS_KHR)) {
testFailed('Program linked before shaders finished compiling.');
} else if (frames <= 6) {
testFailed(`Program should have taken many more than 6 frames to compile. Actual value: ${frames} frames, duration ${performance.now() - start} ms.`);
} else {
console.log(`COMPLETION_STATUS_KHR sucessfully transitioned from false to true in ${frames} frames and ${duration} ms.`);
testPassed(`COMPLETION_STATUS_KHR sucessfully transitioned from false to true`);
}
debug("Checking that status is true when context is lost.");
if (loseContext) {
gl.shaderSource(vs, vertexSource(extraCode));
gl.shaderSource(fs, fragmentSource(extraCode));
gl.compileShader(vs);
gl.compileShader(fs);
gl.linkProgram(program);
loseContext.loseContext();
status = gl.getShaderParameter(vs, COMPLETION_STATUS_KHR);
if (status !== true) testFailed("shader status should be true when context is lost");
status = gl.getProgramParameter(program, COMPLETION_STATUS_KHR);
if (status !== true) testFailed("program status should be true when context is lost");
loseContext.restoreContext();
vs = gl.createShader(gl.VERTEX_SHADER);
fs = gl.createShader(gl.FRAGMENT_SHADER);
program = gl.createProgram();
}
}
finishTest();
})();
async function compileShaders() {
console.log('Compiling shaders');
const gl = canvas.getContext('webgl');
const vs = gl.createShader(gl.VERTEX_SHADER);
const fs = gl.createShader(gl.FRAGMENT_SHADER);
const program = gl.createProgram();
gl.getExtension(wtu.getExtensionWithKnownPrefixes(gl, "KHR_parallel_shader_compile"));
gl.attachShader(program, vs);
gl.attachShader(program, fs);
gl.shaderSource(vs, vertexSource(extraCode));
gl.shaderSource(fs, fragmentSource(extraCode));
gl.compileShader(vs);
gl.compileShader(fs);
gl.linkProgram(program);
while (!gl.getProgramParameter(program, COMPLETION_STATUS_KHR)) {
gl.getShaderParameter(vs, COMPLETION_STATUS_KHR);
gl.getShaderParameter(fs, COMPLETION_STATUS_KHR);
await new Promise(requestAnimationFrame);
}
gl.getProgramParameter(program, gl.LINK_STATUS);
console.log('Compilation finished.');
}
</script>
</body>
</html>

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

@ -25,7 +25,7 @@ const wtu = WebGLTestUtils;
const gl = wtu.create3DContext(); const gl = wtu.create3DContext();
(function() { (function() {
if (!wtu.isWebGL2(gl)) { if (!(gl instanceof WebGL2RenderingContext)) {
if (!gl.getExtension("OES_texture_float")) { if (!gl.getExtension("OES_texture_float")) {
testPassed("No OES_texture_float support -- this is legal"); testPassed("No OES_texture_float support -- this is legal");
return; return;

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

@ -25,7 +25,7 @@ const wtu = WebGLTestUtils;
const gl = wtu.create3DContext(); const gl = wtu.create3DContext();
(function() { (function() {
if (wtu.isWebGL2(gl)) if (gl instanceof WebGL2RenderingContext)
throw new Error("OES_texture_half_float_linear is core in WebGL 2."); throw new Error("OES_texture_half_float_linear is core in WebGL 2.");
const ext = gl.getExtension("OES_texture_half_float"); const ext = gl.getExtension("OES_texture_half_float");

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

@ -252,7 +252,7 @@ function testPVRTCTexture(test) {
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "uploading compressed texture"); wtu.glErrorShouldBe(gl, gl.NO_ERROR, "uploading compressed texture");
gl.generateMipmap(gl.TEXTURE_2D); gl.generateMipmap(gl.TEXTURE_2D);
wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "trying to generate mipmaps from compressed texture"); wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "trying to generate mipmaps from compressed texture");
wtu.clearAndDrawUnitQuad(gl); wtu.drawQuad(gl);
compareRect(width, height, test.channels, width, height, uncompressedData, data, format, undefined, "NEAREST"); compareRect(width, height, test.channels, width, height, uncompressedData, data, format, undefined, "NEAREST");
// Test again with linear filtering. // Test again with linear filtering.
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);

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

@ -226,72 +226,6 @@ function runTestExtension() {
if (contextVersion >= 2) { if (contextVersion >= 2) {
testDXT5_SRGB_ALPHA_PBO(); testDXT5_SRGB_ALPHA_PBO();
} }
// Test TexImage validation on level dimensions combinations.
debug("");
debug("When level equals 0, width and height must be a multiple of 4.");
debug("When level is larger than 0, this constraint doesn't apply.");
ctu.testTexImageLevelDimensions(gl, ext, validFormats, expectedByteLength, getBlockDimensions,
[
{ level: 0, width: 4, height: 3, expectation: gl.INVALID_OPERATION, message: "0: 4x3" },
{ level: 0, width: 3, height: 4, expectation: gl.INVALID_OPERATION, message: "0: 3x4" },
{ level: 0, width: 2, height: 2, expectation: gl.INVALID_OPERATION, message: "0: 2x2" },
{ level: 0, width: 4, height: 4, expectation: gl.NO_ERROR, message: "0: 4x4" },
{ level: 1, width: 2, height: 2, expectation: gl.NO_ERROR, message: "1: 2x2" },
{ level: 2, width: 1, height: 1, expectation: gl.NO_ERROR, message: "2: 1x1" },
]);
ctu.testTexSubImageDimensions(gl, ext, validFormats, expectedByteLength, getBlockDimensions, 16, 16,
[
{ xoffset: 0, yoffset: 0, width: 4, height: 3,
expectation: gl.INVALID_OPERATION, message: "height is not a multiple of 4" },
{ xoffset: 0, yoffset: 0, width: 3, height: 4,
expectation: gl.INVALID_OPERATION, message: "width is not a multiple of 4" },
{ xoffset: 1, yoffset: 0, width: 4, height: 4,
expectation: gl.INVALID_OPERATION, message: "xoffset is not a multiple of 4" },
{ xoffset: 0, yoffset: 1, width: 4, height: 4,
expectation: gl.INVALID_OPERATION, message: "yoffset is not a multiple of 4" },
{ xoffset: 12, yoffset: 12, width: 4, height: 4,
expectation: gl.NO_ERROR, message: "is valid" },
]);
if (contextVersion >= 2) {
debug("");
debug("Testing NPOT textures");
ctu.testTexImageLevelDimensions(gl, ext, validFormats, expectedByteLength, getBlockDimensions,
[
{ level: 0, width: 12, height: 12, expectation: gl.NO_ERROR, message: "0: 12x12 is valid" },
{ level: 1, width: 6, height: 6, expectation: gl.NO_ERROR, message: "1: 6x6, is valid" },
{ level: 2, width: 3, height: 3, expectation: gl.NO_ERROR, message: "2: 3x3, is valid" },
{ level: 3, width: 1, height: 1, expectation: gl.NO_ERROR, message: "3: 1x1, is valid" },
]);
debug("");
debug("Testing partial updates");
ctu.testTexSubImageDimensions(gl, ext, validFormats, expectedByteLength, getBlockDimensions, 12, 12,
[
{ xoffset: 0, yoffset: 0, width: 4, height: 3,
expectation: gl.INVALID_OPERATION, message: "height is not a multiple of 4" },
{ xoffset: 0, yoffset: 0, width: 3, height: 4,
expectation: gl.INVALID_OPERATION, message: "width is not a multiple of 4" },
{ xoffset: 1, yoffset: 0, width: 4, height: 4,
expectation: gl.INVALID_OPERATION, message: "xoffset is not a multiple of 4" },
{ xoffset: 0, yoffset: 1, width: 4, height: 4,
expectation: gl.INVALID_OPERATION, message: "yoffset is not a multiple of 4" },
{ xoffset: 8, yoffset: 8, width: 4, height: 4,
expectation: gl.NO_ERROR, message: "is valid" },
]);
debug("");
debug("Testing immutable NPOT textures");
ctu.testTexStorageLevelDimensions(gl, ext, validFormats, expectedByteLength, getBlockDimensions,
[
{ width: 12, height: 12, expectation: gl.NO_ERROR, message: "0: 12x12 is valid" },
{ width: 6, height: 6, expectation: gl.NO_ERROR, message: "1: 6x6, is valid" },
{ width: 3, height: 3, expectation: gl.NO_ERROR, message: "2: 3x3, is valid" },
{ width: 1, height: 1, expectation: gl.NO_ERROR, message: "3: 1x1, is valid" },
]);
}
} }
function testDXT1_SRGB() { function testDXT1_SRGB() {
@ -683,16 +617,14 @@ function testDXTTexture(test, useTexStorage) {
wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "invalid dimensions"); wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "invalid dimensions");
if (width == 4) { if (width == 4) {
// The width/height of the implied base level must be a multiple of the block size.
gl.compressedTexImage2D(gl.TEXTURE_2D, 1, format, 1, height, 0, data); gl.compressedTexImage2D(gl.TEXTURE_2D, 1, format, 1, height, 0, data);
wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "invalid dimensions for level > 0"); wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "invalid dimensions for level 1");
gl.compressedTexImage2D(gl.TEXTURE_2D, 1, format, 2, height, 0, data); gl.compressedTexImage2D(gl.TEXTURE_2D, 1, format, 2, height, 0, data);
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "valid dimensions for level > 0"); wtu.glErrorShouldBe(gl, gl.NO_ERROR, "valid dimensions for level > 0");
} }
if (height == 4) { if (height == 4) {
// The width/height of the implied base level must be a multiple of the block size.
gl.compressedTexImage2D(gl.TEXTURE_2D, 1, format, width, 1, 0, data); gl.compressedTexImage2D(gl.TEXTURE_2D, 1, format, width, 1, 0, data);
wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "invalid dimensions for level > 0"); wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "invalid dimensions for level 1");
gl.compressedTexImage2D(gl.TEXTURE_2D, 1, format, width, 2, 0, data); gl.compressedTexImage2D(gl.TEXTURE_2D, 1, format, width, 2, 0, data);
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "valid dimensions for level > 0"); wtu.glErrorShouldBe(gl, gl.NO_ERROR, "valid dimensions for level > 0");
} }

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

@ -12,7 +12,7 @@ found in the LICENSE.txt file.
<script src="../../js/js-test-pre.js"></script> <script src="../../js/js-test-pre.js"></script>
<script src="../../js/webgl-test-utils.js"></script> <script src="../../js/webgl-test-utils.js"></script>
<script src="../../js/tests/compressed-texture-utils.js"></script> <script src="../../js/tests/compressed-texture-utils.js"></script>
<title>WebGL WEBGL_compressed_texture_s3tc and EXT_texture_compression_rgtc Conformance Tests</title> <title>WebGL WEBGL_compressed_texture_s3tc Conformance Tests</title>
<style> <style>
img { img {
border: 1px solid black; border: 1px solid black;
@ -35,7 +35,7 @@ img {
<div id="console"></div> <div id="console"></div>
<script> <script>
"use strict"; "use strict";
description("This test verifies the functionality of the WEBGL_compressed_texture_s3tc extension, if it is available. It also tests the related formats from the EXT_texture_compression_rgtc extension."); description("This test verifies the functionality of the WEBGL_compressed_texture_s3tc extension, if it is available.");
debug(""); debug("");
@ -130,31 +130,6 @@ var img_4x4_rgba_dxt5 = new Uint8Array([
0x00, 0xF8, 0xE0, 0x07, 0x1B, 0x5B, 0xAB, 0xFF 0x00, 0xF8, 0xE0, 0x07, 0x1B, 0x5B, 0xAB, 0xFF
]); ]);
// BC4 - just the alpha block from BC3 above, interpreted as the red channel.
// See http://www.reedbeta.com/blog/understanding-bcn-texture-compression-formats/#bc4
// for format details.
var img_4x4_r_bc4 = new Uint8Array([
0xFF, 0x00, 0x88, 0x16, 0x8D, 0x1A, 0x3B, 0xD6,
]);
// BC5 - Two BC3 alpha blocks, interpreted as the red and green channels.
var img_4x4_rg_bc5 = new Uint8Array([
0xFF, 0x00, 0x88, 0x16, 0x8D, 0x1A, 0x3B, 0xD6,
0x00, 0xFF, 0x88, 0x16, 0x8D, 0x1A, 0x3B, 0xD6,
]);
// Signed BC4 - change endpoints to use full -1 to 1 range.
var img_4x4_signed_r_bc4 = new Uint8Array([
0x7F, 0x80, 0x88, 0x16, 0x8D, 0x1A, 0x3B, 0xD6,
]);
// Signed BC5 - Two BC3 alpha blocks, interpreted as the red and green channels.
var img_4x4_signed_rg_bc5 = new Uint8Array([
0x7F, 0x80, 0x88, 0x16, 0x8D, 0x1A, 0x3B, 0xD6,
0x80, 0x7F, 0x88, 0x16, 0x8D, 0x1A, 0x3B, 0xD6,
]);
/* /*
8x8 block endpoints use half-intensity values (appear darker than 4x4) 8x8 block endpoints use half-intensity values (appear darker than 4x4)
*/ */
@ -176,18 +151,6 @@ var img_8x8_rgba_dxt5 = new Uint8Array([
0xff,0x69,0x00,0x00,0x00,0x01,0x10,0x00,0x0f,0x78,0xe0,0x03,0x11,0x10,0x15,0x00, 0xff,0x69,0x00,0x00,0x00,0x01,0x10,0x00,0x0f,0x78,0xe0,0x03,0x11,0x10,0x15,0x00,
0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0xef,0x03,0xef,0x00,0x11,0x10,0x15,0x00 0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0xef,0x03,0xef,0x00,0x11,0x10,0x15,0x00
]); ]);
var img_8x8_r_bc4 = new Uint8Array([
0x7F, 0x00, 0x88, 0x16, 0x8D, 0x1A, 0x3B, 0xD6,
0x7F, 0x00, 0x88, 0x16, 0x8D, 0x1A, 0x3B, 0xD6,
0x7F, 0x00, 0x88, 0x16, 0x8D, 0x1A, 0x3B, 0xD6,
0x7F, 0x00, 0x88, 0x16, 0x8D, 0x1A, 0x3B, 0xD6,
]);
var img_8x8_rg_bc5 = new Uint8Array([
0x7F, 0x00, 0x88, 0x16, 0x8D, 0x1A, 0x3B, 0xD6, 0x00, 0x7F, 0x88, 0x16, 0x8D, 0x1A, 0x3B, 0xD6,
0x7F, 0x00, 0x88, 0x16, 0x8D, 0x1A, 0x3B, 0xD6, 0x00, 0x7F, 0x88, 0x16, 0x8D, 0x1A, 0x3B, 0xD6,
0x7F, 0x00, 0x88, 0x16, 0x8D, 0x1A, 0x3B, 0xD6, 0x00, 0x7F, 0x88, 0x16, 0x8D, 0x1A, 0x3B, 0xD6,
0x7F, 0x00, 0x88, 0x16, 0x8D, 0x1A, 0x3B, 0xD6, 0x00, 0x7F, 0x88, 0x16, 0x8D, 0x1A, 0x3B, 0xD6,
]);
var wtu = WebGLTestUtils; var wtu = WebGLTestUtils;
var ctu = CompressedTextureUtils; var ctu = CompressedTextureUtils;
@ -196,7 +159,6 @@ var canvas = document.getElementById("canvas");
var gl = wtu.create3DContext(canvas, {antialias: false}); var gl = wtu.create3DContext(canvas, {antialias: false});
var program = wtu.setupTexturedQuad(gl); var program = wtu.setupTexturedQuad(gl);
var ext = null; var ext = null;
var ext_rgtc = {};
var vao = null; var vao = null;
var validFormats = { var validFormats = {
COMPRESSED_RGB_S3TC_DXT1_EXT : 0x83F0, COMPRESSED_RGB_S3TC_DXT1_EXT : 0x83F0,
@ -226,14 +188,6 @@ if (!gl) {
wtu.runExtensionSupportedTest(gl, "WEBGL_compressed_texture_s3tc", true); wtu.runExtensionSupportedTest(gl, "WEBGL_compressed_texture_s3tc", true);
runTestExtension(); runTestExtension();
} }
ext_rgtc = wtu.getExtensionWithKnownPrefixes(gl, "EXT_texture_compression_rgtc");
if (ext_rgtc) {
ext = ext || {};
// Make ctu.formatToString work for rgtc enums.
for (const name in ext_rgtc)
ext[name] = ext_rgtc[name];
runTestRGTC();
}
} }
function expectedByteLength(width, height, format) { function expectedByteLength(width, height, format) {
@ -267,145 +221,6 @@ function runTestExtension() {
if (contextVersion >= 2) { if (contextVersion >= 2) {
testDXT5_RGBA_PBO(); testDXT5_RGBA_PBO();
} }
// Test TexImage validation on level dimensions combinations.
debug("");
debug("When level equals 0, width and height must be a multiple of 4.");
debug("When level is larger than 0, this constraint doesn't apply.");
ctu.testTexImageLevelDimensions(gl, ext, validFormats, expectedByteLength, getBlockDimensions,
[
{ level: 0, width: 4, height: 3, expectation: gl.INVALID_OPERATION, message: "0: 4x3" },
{ level: 0, width: 3, height: 4, expectation: gl.INVALID_OPERATION, message: "0: 3x4" },
{ level: 0, width: 2, height: 2, expectation: gl.INVALID_OPERATION, message: "0: 2x2" },
{ level: 0, width: 4, height: 4, expectation: gl.NO_ERROR, message: "0: 4x4" },
{ level: 1, width: 2, height: 2, expectation: gl.NO_ERROR, message: "1: 2x2" },
{ level: 2, width: 1, height: 1, expectation: gl.NO_ERROR, message: "2: 1x1" },
]);
ctu.testTexSubImageDimensions(gl, ext, validFormats, expectedByteLength, getBlockDimensions, 16, 16,
[
{ xoffset: 0, yoffset: 0, width: 4, height: 3,
expectation: gl.INVALID_OPERATION, message: "height is not a multiple of 4" },
{ xoffset: 0, yoffset: 0, width: 3, height: 4,
expectation: gl.INVALID_OPERATION, message: "width is not a multiple of 4" },
{ xoffset: 1, yoffset: 0, width: 4, height: 4,
expectation: gl.INVALID_OPERATION, message: "xoffset is not a multiple of 4" },
{ xoffset: 0, yoffset: 1, width: 4, height: 4,
expectation: gl.INVALID_OPERATION, message: "yoffset is not a multiple of 4" },
{ xoffset: 12, yoffset: 12, width: 4, height: 4,
expectation: gl.NO_ERROR, message: "is valid" },
]);
if (contextVersion >= 2) {
debug("");
debug("Testing NPOT textures");
ctu.testTexImageLevelDimensions(gl, ext, validFormats, expectedByteLength, getBlockDimensions,
[
{ level: 0, width: 0, height: 0, expectation: gl.NO_ERROR, message: "0: 0x0 is valid" },
{ level: 0, width: 1, height: 1, expectation: gl.INVALID_OPERATION, message: "0: 1x1 is invalid" },
{ level: 0, width: 2, height: 2, expectation: gl.INVALID_OPERATION, message: "0: 2x2 is invalid" },
{ level: 0, width: 3, height: 3, expectation: gl.INVALID_OPERATION, message: "0: 3x3 is invalid" },
{ level: 0, width: 10, height: 10, expectation: gl.INVALID_OPERATION, message: "0: 10x10 is invalid" },
{ level: 0, width: 11, height: 11, expectation: gl.INVALID_OPERATION, message: "0: 11x11 is invalid" },
{ level: 0, width: 11, height: 12, expectation: gl.INVALID_OPERATION, message: "0: 11x12 is invalid" },
{ level: 0, width: 12, height: 11, expectation: gl.INVALID_OPERATION, message: "0: 12x11 is invalid" },
{ level: 0, width: 12, height: 12, expectation: gl.NO_ERROR, message: "0: 12x12 is valid" },
{ level: 1, width: 0, height: 0, expectation: gl.NO_ERROR, message: "1: 0x0, is valid" },
{ level: 1, width: 3, height: 3, expectation: gl.INVALID_OPERATION, message: "1: 3x3, is invalid" },
{ level: 1, width: 5, height: 5, expectation: gl.INVALID_OPERATION, message: "1: 5x5, is invalid" },
{ level: 1, width: 5, height: 6, expectation: gl.INVALID_OPERATION, message: "1: 5x6, is invalid" },
{ level: 1, width: 6, height: 5, expectation: gl.INVALID_OPERATION, message: "1: 6x5, is invalid" },
{ level: 1, width: 6, height: 6, expectation: gl.NO_ERROR, message: "1: 6x6, is valid" },
{ level: 2, width: 0, height: 0, expectation: gl.NO_ERROR, message: "2: 0x0, is valid" },
{ level: 2, width: 3, height: 3, expectation: gl.NO_ERROR, message: "2: 3x3, is valid" },
{ level: 3, width: 1, height: 3, expectation: gl.NO_ERROR, message: "3: 1x3, is valid" },
{ level: 3, width: 1, height: 1, expectation: gl.NO_ERROR, message: "3: 1x1, is valid" },
]);
debug("");
debug("Testing partial updates");
ctu.testTexSubImageDimensions(gl, ext, validFormats, expectedByteLength, getBlockDimensions, 12, 12,
[
{ xoffset: 0, yoffset: 0, width: 4, height: 3,
expectation: gl.INVALID_OPERATION, message: "height is not a multiple of 4" },
{ xoffset: 0, yoffset: 0, width: 3, height: 4,
expectation: gl.INVALID_OPERATION, message: "width is not a multiple of 4" },
{ xoffset: 1, yoffset: 0, width: 4, height: 4,
expectation: gl.INVALID_OPERATION, message: "xoffset is not a multiple of 4" },
{ xoffset: 0, yoffset: 1, width: 4, height: 4,
expectation: gl.INVALID_OPERATION, message: "yoffset is not a multiple of 4" },
{ xoffset: 8, yoffset: 8, width: 4, height: 4,
expectation: gl.NO_ERROR, message: "is valid" },
]);
debug("");
debug("Testing immutable NPOT textures");
ctu.testTexStorageLevelDimensions(gl, ext, validFormats, expectedByteLength, getBlockDimensions,
[
{ width: 12, height: 12, expectation: gl.NO_ERROR, message: "0: 12x12 is valid" },
{ width: 6, height: 6, expectation: gl.NO_ERROR, message: "1: 6x6, is valid" },
{ width: 3, height: 3, expectation: gl.NO_ERROR, message: "2: 3x3, is valid" },
{ width: 1, height: 1, expectation: gl.NO_ERROR, message: "3: 1x1, is valid" },
]);
}
}
function runTestRGTC() {
var tests = [
{ width: 4,
height: 4,
channels: 1,
data: img_4x4_r_bc4,
format: ext_rgtc.COMPRESSED_RED_RGTC1_EXT,
hasAlpha: false,
},
{ width: 4,
height: 4,
channels: 1,
data: img_4x4_signed_r_bc4,
format: ext_rgtc.COMPRESSED_SIGNED_RED_RGTC1_EXT,
hasAlpha: false,
},
{ width: 4,
height: 4,
channels: 2,
data: img_4x4_rg_bc5,
format: ext_rgtc.COMPRESSED_RED_GREEN_RGTC2_EXT,
hasAlpha: false,
},
{ width: 4,
height: 4,
channels: 2,
data: img_4x4_signed_rg_bc5,
format: ext_rgtc.COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT,
hasAlpha: false,
},
{ width: 8,
height: 8,
channels: 2,
data: img_8x8_r_bc4,
format: ext_rgtc.COMPRESSED_RED_RGTC1_EXT,
hasAlpha: false,
subX0: 0,
subY0: 0,
subWidth: 4,
subHeight: 4,
subData: img_4x4_r_bc4,
},
{ width: 8,
height: 8,
channels: 2,
data: img_8x8_rg_bc5,
format: ext_rgtc.COMPRESSED_RED_GREEN_RGTC2_EXT,
hasAlpha: false,
subX0: 0,
subY0: 0,
subWidth: 4,
subHeight: 4,
subData: img_4x4_rg_bc5,
},
];
testDXTTextures(tests);
} }
function testDXT1_RGB() { function testDXT1_RGB() {
@ -550,12 +365,6 @@ function uncompressDXTBlock(
} }
return r; return r;
} }
var isBC45 = ext_rgtc &&
(format == ext_rgtc.COMPRESSED_RED_RGTC1_EXT ||
format == ext_rgtc.COMPRESSED_RED_GREEN_RGTC2_EXT ||
format == ext_rgtc.COMPRESSED_SIGNED_RED_RGTC1_EXT ||
format == ext_rgtc.COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT);
if (!isBC45) {
var isDXT1 = format == ext.COMPRESSED_RGB_S3TC_DXT1_EXT || var isDXT1 = format == ext.COMPRESSED_RGB_S3TC_DXT1_EXT ||
format == ext.COMPRESSED_RGBA_S3TC_DXT1_EXT; format == ext.COMPRESSED_RGBA_S3TC_DXT1_EXT;
var colorOffset = srcOffset + (isDXT1 ? 0 : 8); var colorOffset = srcOffset + (isDXT1 ? 0 : 8);
@ -570,9 +379,6 @@ function uncompressDXTBlock(
c0gtc1 ? mix(2, rgba0, rgba1, 3) : mix(1, rgba0, rgba1, 2), c0gtc1 ? mix(2, rgba0, rgba1, 3) : mix(1, rgba0, rgba1, 2),
c0gtc1 ? mix(2, rgba1, rgba0, 3) : [0, 0, 0, 255] c0gtc1 ? mix(2, rgba1, rgba0, 3) : [0, 0, 0, 255]
]; ];
}
const isSigned = ext_rgtc && (format == ext_rgtc.COMPRESSED_SIGNED_RED_RGTC1_EXT || format == ext_rgtc.COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT);
const signedSrc = new Int8Array(src);
// yea I know there is a lot of math in this inner loop. // yea I know there is a lot of math in this inner loop.
// so sue me. // so sue me.
@ -580,21 +386,32 @@ function uncompressDXTBlock(
var pixels = src[colorOffset + 4 + yy]; var pixels = src[colorOffset + 4 + yy];
for (var xx = 0; xx < 4; ++xx) { for (var xx = 0; xx < 4; ++xx) {
var dstOff = ((destY + yy) * destWidth + destX + xx) * 4; var dstOff = ((destY + yy) * destWidth + destX + xx) * 4;
if (!isBC45) {
var code = (pixels >> (xx * 2)) & 0x3; var code = (pixels >> (xx * 2)) & 0x3;
var srcColor = colors[code]; var srcColor = colors[code];
}
var alpha; var alpha;
var rgChannel2 = 0; switch (format) {
let decodeAlpha = (offset) => { case ext.COMPRESSED_RGB_S3TC_DXT1_EXT:
let alpha; alpha = 255;
var alpha0 = (isSigned ? signedSrc : src)[offset + 0]; break;
var alpha1 = (isSigned ? signedSrc : src)[offset + 1]; case ext.COMPRESSED_RGBA_S3TC_DXT1_EXT:
alpha = (code == 3 && !c0gtc1) ? 0 : 255;
break;
case ext.COMPRESSED_RGBA_S3TC_DXT3_EXT:
{
var alpha0 = src[srcOffset + yy * 2 + (xx >> 1)];
var alpha1 = (alpha0 >> ((xx % 2) * 4)) & 0xF;
alpha = alpha1 | (alpha1 << 4);
}
break;
case ext.COMPRESSED_RGBA_S3TC_DXT5_EXT:
{
var alpha0 = src[srcOffset + 0];
var alpha1 = src[srcOffset + 1];
var alphaOff = (yy >> 1) * 3 + 2; var alphaOff = (yy >> 1) * 3 + 2;
var alphaBits = var alphaBits =
src[offset + alphaOff + 0] + src[srcOffset + alphaOff + 0] +
src[offset + alphaOff + 1] * 256 + src[srcOffset + alphaOff + 1] * 256 +
src[offset + alphaOff + 2] * 65536; src[srcOffset + alphaOff + 2] * 65536;
var alphaShift = (yy % 2) * 12 + xx * 3; var alphaShift = (yy % 2) * 12 + xx * 3;
var alphaCode = (alphaBits >> alphaShift) & 0x7; var alphaCode = (alphaBits >> alphaShift) & 0x7;
if (alpha0 > alpha1) { if (alpha0 > alpha1) {
@ -628,59 +445,23 @@ function uncompressDXTBlock(
break; break;
} }
} }
return alpha;
} }
switch (format) {
case ext.COMPRESSED_RGB_S3TC_DXT1_EXT:
alpha = 255;
break;
case ext.COMPRESSED_RGBA_S3TC_DXT1_EXT:
alpha = (code == 3 && !c0gtc1) ? 0 : 255;
break;
case ext.COMPRESSED_RGBA_S3TC_DXT3_EXT:
{
var alpha0 = src[srcOffset + yy * 2 + (xx >> 1)];
var alpha1 = (alpha0 >> ((xx % 2) * 4)) & 0xF;
alpha = alpha1 | (alpha1 << 4);
}
break;
case ext_rgtc.COMPRESSED_RED_GREEN_RGTC2_EXT:
case ext_rgtc.COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT:
rgChannel2 = decodeAlpha(srcOffset + 8);
// FALLTHROUGH
case ext.COMPRESSED_RGBA_S3TC_DXT5_EXT:
case ext_rgtc.COMPRESSED_RED_RGTC1_EXT:
case ext_rgtc.COMPRESSED_SIGNED_RED_RGTC1_EXT:
alpha = decodeAlpha(srcOffset);
break; break;
default: default:
throw "bad format"; throw "bad format";
} }
if (isBC45) {
destBuffer[dstOff + 0] = alpha;
destBuffer[dstOff + 1] = rgChannel2;
destBuffer[dstOff + 2] = 0;
destBuffer[dstOff + 3] = 255;
if (isSigned) {
destBuffer[dstOff + 0] = Math.max(0, alpha) * 2;
destBuffer[dstOff + 1] = Math.max(0, rgChannel2) * 2;
}
} else {
destBuffer[dstOff + 0] = srcColor[0]; destBuffer[dstOff + 0] = srcColor[0];
destBuffer[dstOff + 1] = srcColor[1]; destBuffer[dstOff + 1] = srcColor[1];
destBuffer[dstOff + 2] = srcColor[2]; destBuffer[dstOff + 2] = srcColor[2];
destBuffer[dstOff + 3] = alpha; destBuffer[dstOff + 3] = alpha;
} }
} }
}
} }
function getBlockSize(format) { function getBlockSize(format) {
var isDXT1 = format == ext.COMPRESSED_RGB_S3TC_DXT1_EXT || var isDXT1 = format == ext.COMPRESSED_RGB_S3TC_DXT1_EXT ||
format == ext.COMPRESSED_RGBA_S3TC_DXT1_EXT; format == ext.COMPRESSED_RGBA_S3TC_DXT1_EXT;
var isBC4 = ext_rgtc && (format == ext_rgtc.COMPRESSED_RED_RGTC1_EXT || format == ext_rgtc.COMPRESSED_SIGNED_RED_RGTC1_EXT); return isDXT1 ? 8 : 16;
return isDXT1 || isBC4 ? 8 : 16;
} }
function uncompressDXT(width, height, data, format) { function uncompressDXT(width, height, data, format) {
@ -706,10 +487,8 @@ function uncompressDXTIntoSubRegion(width, height, subX0, subY0, subWidth, subHe
throw "bad dimension"; throw "bad dimension";
var dest = new Uint8Array(width * height * 4); var dest = new Uint8Array(width * height * 4);
// Zero-filled DXT1 or BC4/5 texture represents [0, 0, 0, 255] // Zero-filled DXT1 texture represents [0, 0, 0, 255]
if (format == ext.COMPRESSED_RGB_S3TC_DXT1_EXT || format == ext.COMPRESSED_RGBA_S3TC_DXT1_EXT || if (format == ext.COMPRESSED_RGB_S3TC_DXT1_EXT || format == ext.COMPRESSED_RGBA_S3TC_DXT1_EXT) {
format == ext.COMPRESSED_RED_RGTC1_EXT || format == ext.COMPRESSED_SIGNED_RED_RGTC1_EXT ||
format == ext.COMPRESSED_RED_GREEN_RGTC2_EXT || format == ext.COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT) {
for (var i = 3; i < dest.length; i += 4) dest[i] = 255; for (var i = 3; i < dest.length; i += 4) dest[i] = 255;
} }
var blocksAcross = subWidth / 4; var blocksAcross = subWidth / 4;
@ -833,16 +612,14 @@ function testDXTTexture(test, useTexStorage) {
wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "invalid dimensions"); wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "invalid dimensions");
if (width == 4) { if (width == 4) {
// The width/height of the implied base level must be a multiple of the block size.
gl.compressedTexImage2D(gl.TEXTURE_2D, 1, format, 1, height, 0, data); gl.compressedTexImage2D(gl.TEXTURE_2D, 1, format, 1, height, 0, data);
wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "invalid dimensions for level > 0"); wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "invalid dimensions for level 1");
gl.compressedTexImage2D(gl.TEXTURE_2D, 1, format, 2, height, 0, data); gl.compressedTexImage2D(gl.TEXTURE_2D, 1, format, 2, height, 0, data);
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "valid dimensions for level > 0"); wtu.glErrorShouldBe(gl, gl.NO_ERROR, "valid dimensions for level > 0");
} }
if (height == 4) { if (height == 4) {
// The width/height of the implied base level must be a multiple of the block size.
gl.compressedTexImage2D(gl.TEXTURE_2D, 1, format, width, 1, 0, data); gl.compressedTexImage2D(gl.TEXTURE_2D, 1, format, width, 1, 0, data);
wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "invalid dimensions for level > 0"); wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "invalid dimensions for level 1");
gl.compressedTexImage2D(gl.TEXTURE_2D, 1, format, width, 2, 0, data); gl.compressedTexImage2D(gl.TEXTURE_2D, 1, format, width, 2, 0, data);
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "valid dimensions for level > 0"); wtu.glErrorShouldBe(gl, gl.NO_ERROR, "valid dimensions for level > 0");
} }
@ -863,14 +640,6 @@ function testDXTTexture(test, useTexStorage) {
case ext.COMPRESSED_RGBA_S3TC_DXT5_EXT: case ext.COMPRESSED_RGBA_S3TC_DXT5_EXT:
wrongFormat = ext.COMPRESSED_RGBA_S3TC_DXT3_EXT; wrongFormat = ext.COMPRESSED_RGBA_S3TC_DXT3_EXT;
break; break;
case ext_rgtc.COMPRESSED_RED_RGTC1_EXT:
case ext_rgtc.COMPRESSED_SIGNED_RED_RGTC1_EXT:
wrongFormat = ext_rgtc.COMPRESSED_RED_GREEN_RGTC2_EXT;
break;
case ext_rgtc.COMPRESSED_RED_GREEN_RGTC2_EXT:
case ext_rgtc.COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT:
wrongFormat = ext_rgtc.COMPRESSED_RED_RGTC1_EXT;
break;
} }
gl.compressedTexSubImage2D(gl.TEXTURE_2D, 0, 0, 0, width, height, wrongFormat, data); gl.compressedTexSubImage2D(gl.TEXTURE_2D, 0, 0, 0, width, height, wrongFormat, data);

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

@ -146,7 +146,6 @@ const wtu = WebGLTestUtils;
const canvas = document.getElementById("canvas"); const canvas = document.getElementById("canvas");
const gl = wtu.create3DContext(canvas); const gl = wtu.create3DContext(canvas);
const instancedExt = gl && gl.getExtension('ANGLE_instanced_arrays'); const instancedExt = gl && gl.getExtension('ANGLE_instanced_arrays');
const bufferUsageSet = [ gl.STATIC_DRAW, gl.DYNAMIC_DRAW ];
// Check if the extension is either both enabled and supported or // Check if the extension is either both enabled and supported or
// not enabled and not supported. // not enabled and not supported.
@ -188,18 +187,18 @@ function runTest() {
function doTest(ext, instanced) { function doTest(ext, instanced) {
function runValidationTests(bufferUsage) { function runValidationTests() {
const vertexBuffer = gl.createBuffer(); const vertexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer); 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 ]), bufferUsage); 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(); const indexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer); gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint8Array([ 0, 1, 2, 0]), bufferUsage); gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint8Array([ 0, 1, 2, 0]), gl.STATIC_DRAW);
const instanceBuffer = gl.createBuffer(); const instanceBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, instanceBuffer); gl.bindBuffer(gl.ARRAY_BUFFER, instanceBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([ 0, 1, 2, 3 ]), bufferUsage); 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]); const program = wtu.setupProgram(gl, ["vshaderNoDrawID", "fshader"], ["vPosition", "vInstance"], [0, 1]);
expectTrue(program != null, "can compile simple program"); expectTrue(program != null, "can compile simple program");
@ -355,7 +354,7 @@ function doTest(ext, instanced) {
} }
} }
function runShaderTests(bufferUsage) { function runShaderTests() {
const illegalProgram = wtu.setupProgram(gl, ["vshaderIllegalDrawID", "fshader"], ["vPosition"], [0]); const illegalProgram = wtu.setupProgram(gl, ["vshaderIllegalDrawID", "fshader"], ["vPosition"], [0]);
expectTrue(illegalProgram == null, "cannot compile program with gl_DrawID but no extension directive"); expectTrue(illegalProgram == null, "cannot compile program with gl_DrawID but no extension directive");
@ -364,14 +363,14 @@ function doTest(ext, instanced) {
expectTrue(drawIDProgram !== null, "can compile program with gl_DrawID"); expectTrue(drawIDProgram !== null, "can compile program with gl_DrawID");
gl.useProgram(drawIDProgram); gl.useProgram(drawIDProgram);
gl.bindBuffer(gl.ARRAY_BUFFER, gl.createBuffer()); 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 ]), bufferUsage); 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.enableVertexAttribArray(0);
gl.vertexAttribPointer(0, 2, gl.FLOAT, false, 0, 0); gl.vertexAttribPointer(0, 2, gl.FLOAT, false, 0, 0);
gl.drawArrays(gl.TRIANGLES, 0, 6); gl.drawArrays(gl.TRIANGLES, 0, 6);
wtu.checkCanvas(gl, [0, 255, 0, 255], "gl_DrawID is 0 for non-Multi* draw calls", 0); wtu.checkCanvas(gl, [0, 255, 0, 255], "gl_DrawID is 0 for non-Multi* draw calls", 0);
} }
function runPixelTests(bufferUsage, useSharedArrayBuffer) { function runPixelTests() {
// An array of quads is tiled across the screen. // An array of quads is tiled across the screen.
// gl_DrawID is checked by using it to select the color of the draw. // gl_DrawID is checked by using it to select the color of the draw.
// Instanced entrypoints are tested here scaling and then instancing the // Instanced entrypoints are tested here scaling and then instancing the
@ -439,16 +438,16 @@ function doTest(ext, instanced) {
const instanceBuffer = gl.createBuffer(); const instanceBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, nonIndexedVertexBuffer); gl.bindBuffer(gl.ARRAY_BUFFER, nonIndexedVertexBuffer);
gl.bufferData(gl.ARRAY_BUFFER, nonIndexedVertices, bufferUsage); gl.bufferData(gl.ARRAY_BUFFER, nonIndexedVertices, gl.STATIC_DRAW);
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer); gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
gl.bufferData(gl.ARRAY_BUFFER, vertices, bufferUsage); gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer); gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indices, bufferUsage); gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indices, gl.STATIC_DRAW);
gl.bindBuffer(gl.ARRAY_BUFFER, instanceBuffer); gl.bindBuffer(gl.ARRAY_BUFFER, instanceBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([1, 2, 3, 4]), bufferUsage); gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([1, 2, 3, 4]), gl.STATIC_DRAW);
function checkResult(config, msg) { function checkResult(config, msg) {
const rects = []; const rects = [];
@ -506,18 +505,10 @@ function doTest(ext, instanced) {
wtu.checkCanvasRects(gl, rects); wtu.checkCanvasRects(gl, rects);
} }
function newIntArray(count) { const firsts = new Uint32Array(tri_count);
if (!useSharedArrayBuffer) { const counts = new Uint32Array(tri_count);
return new Int32Array(count); const offsets = new Uint32Array(tri_count);
} const instances = new Uint32Array(tri_count);
let sab = new SharedArrayBuffer(count * Int32Array.BYTES_PER_ELEMENT);
return new Int32Array(sab);
}
const firsts = newIntArray(tri_count);
const counts = newIntArray(tri_count);
const offsets = newIntArray(tri_count);
const instances = newIntArray(tri_count);
for (let i = 0; i < firsts.length; ++i) firsts[i] = i * 3; for (let i = 0; i < firsts.length; ++i) firsts[i] = i * 3;
counts.fill(3); counts.fill(3);
@ -529,7 +520,7 @@ function doTest(ext, instanced) {
const offsetsOffset = countsOffset + counts.length; const offsetsOffset = countsOffset + counts.length;
const instancesOffset = offsetsOffset + instances.length; const instancesOffset = offsetsOffset + instances.length;
const buffer = newIntArray(firstsOffset + firsts.length + counts.length + offsets.length + instances.length); const buffer = new Uint32Array(firstsOffset + firsts.length + counts.length + offsets.length + instances.length);
buffer.set(firsts, firstsOffset); buffer.set(firsts, firstsOffset);
buffer.set(counts, countsOffset); buffer.set(counts, countsOffset);
buffer.set(offsets, offsetsOffset); buffer.set(offsets, offsetsOffset);
@ -672,8 +663,6 @@ function doTest(ext, instanced) {
config.instanced ? ' instanced' : '' config.instanced ? ' instanced' : ''
) + ( ) + (
config.drawID ? ' with gl_DrawID' : '' config.drawID ? ' with gl_DrawID' : ''
) + (
useSharedArrayBuffer ? ' and SharedArrayBuffer' : ''
)); ));
gl.disableVertexAttribArray(0); gl.disableVertexAttribArray(0);
@ -832,18 +821,9 @@ function doTest(ext, instanced) {
} }
} }
for (let i = 0; i < bufferUsageSet.length; i++) { runValidationTests();
let bufferUsage = bufferUsageSet[i]; runShaderTests();
debug("Testing with BufferUsage = " + bufferUsage); runPixelTests();
runValidationTests(bufferUsage);
runShaderTests(bufferUsage);
runPixelTests(bufferUsage, false);
}
// Run a subset of the pixel tests with SharedArrayBuffer if supported.
if (window.SharedArrayBuffer) {
runPixelTests(bufferUsageSet[0], true);
}
} }
runTest(); runTest();

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

@ -1,211 +0,0 @@
<!--
Copyright (c) 2021 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 src="../../js/tests/out-of-bounds-test.js"></script>
<script src="../../../../extensions/proposals/WEBGL_webcodecs_video_frame/webgl_webcodecs_video_frame.js"></script>
<style>
canvas {
padding: 10px;
background: gold;
}
button {
background-color: #555555;
border: none;
color: white;
padding: 15px 32px;
width: 150px;
text-align: center;
display: block;
font-size: 16px;
}
</style>
</head>
<body>
<canvas id="src" width="640" height="480"></canvas>
<canvas id="dst" width="640" height="480"></canvas>
<p id="info"></p>
<div id="description"></div>
<div id="console"></div>
<script>
"use strict";
description("Test of importing Videoframe from Webcodecs to Webgl");
const kIsRunningTest = true;
const kMaxFrame = 10;
const kTestPixel = [255, 128, 0, 255];
// Sum of pixel difference of R/G/B channel. Use to decide whether a
// pixel is matched with another.
const codec_string = "vp09.00.51.08.00";
let wtu = WebGLTestUtils;
let cnv = document.getElementById("src");
let src_width = cnv.width;
let src_height = cnv.height;
let src_color = "rgba(" + kTestPixel[0].toString() + "," + kTestPixel[1].toString() + ","
+ kTestPixel[2].toString() + "," + kTestPixel[3].toString() + ")";
let frame_counter = 0;
let pixelCompareTolerance = 5;
function getQueryVariable(variable) {
var query = window.location.search.substring(1);
var vars = query.split("&");
for (var i = 0; i < vars.length; i++) {
var pair = vars[i].split("=");
if (pair[0] == variable) { return pair[1]; }
}
return false;
}
let th = parseInt(getQueryVariable('threshold'));
if (!isNaN(th))
pixelCompareTolerance = th;
async function startDrawing() {
let cnv = document.getElementById("src");
var ctx = cnv.getContext('2d', { alpha: false });
ctx.fillStyle = src_color;
let drawOneFrame = function (time) {
ctx.fillStyle = src_color;
ctx.fillRect(0, 0, src_width, src_height);
window.requestAnimationFrame(drawOneFrame);
}
window.requestAnimationFrame(drawOneFrame);
}
function captureAndEncode(processChunk) {
let cnv = document.getElementById("src");
let fps = 60;
let pending_outputs = 0;
let stream = cnv.captureStream(fps);
let processor = new MediaStreamTrackProcessor(stream.getVideoTracks()[0]);
const init = {
output: (chunk) => {
testPassed("Encode frame successfully.");
pending_outputs--;
processChunk(chunk);
},
error: (e) => {
testFailed("Failed to encode frame.");
finishTest();
vtr.stop();
}
};
const config = {
codec: codec_string,
width: cnv.width,
height: cnv.height,
bitrate: 10e6,
framerate: fps,
};
let encoder = new VideoEncoder(init);
encoder.configure(config);
const frame_reader = processor.readable.getReader();
frame_reader.read().then(function processFrame({done, value}) {
if (done)
return;
if (pending_outputs > 30) {
console.log("drop this frame");
// Too many frames in flight, encoder is overwhelmed
// let's drop this frame.
value.close();
frame_reader.read().then(processFrame);
return;
}
if(frame_counter == kMaxFrame) {
frame_reader.releaseLock();
processor.readable.cancel();
value.close();
return;
}
frame_counter++;
pending_outputs++;
const insert_keyframe = (frame_counter % 150) == 0;
encoder.encode(value, { keyFrame: insert_keyframe });
frame_reader.read().then(processFrame);
});
}
function startDecodingAndRendering(cnv, handleFrame) {
const init = {
output: handleFrame,
error: (e) => {
testFailed("Failed to decode frame.");
finishTest();
}
};
const config = {
codec: codec_string,
codedWidth: cnv.width,
codedHeight: cnv.height,
acceleration: "deny",
};
let decoder = new VideoDecoder(init);
decoder.configure(config);
return decoder;
}
function isFramePixelMatched(gl, th_per_pixel = pixelCompareTolerance) {
WebGLTestUtils.checkCanvasRect(gl, 0, 0, src_width, src_width, kTestPixel, "should be orange", pixelCompareTolerance)
}
function main() {
if (!("VideoEncoder" in window)) {
testPassed("WebCodecs API is not supported.");
finishTest();
return;
}
let cnv = document.getElementById("dst");
let webgl_webcodecs_test_context = {
maxFrameTested: kMaxFrame,
displayed_frame: 0,
isFramePixelMatched: isFramePixelMatched,
testFailed: testFailed,
testPassed: testPassed,
finishTest: finishTest
};
setTestMode(webgl_webcodecs_test_context);
let handleFrame = requestWebGLVideoFrameHandler(cnv);
if (handleFrame === null) {
finishTest();
return;
}
startDrawing();
let decoder = startDecodingAndRendering(cnv, handleFrame);
captureAndEncode((chunk) => {
decoder.decode(chunk);
});
}
document.body.onload = main;
</script>
</body>
</html>

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

@ -5,7 +5,6 @@
--min-version 1.0.3 array-of-struct-with-int-first-position.html --min-version 1.0.3 array-of-struct-with-int-first-position.html
--min-version 1.0.4 assign-to-swizzled-twice-in-function.html --min-version 1.0.4 assign-to-swizzled-twice-in-function.html
--min-version 1.0.4 bool-type-cast-bug-int-float.html --min-version 1.0.4 bool-type-cast-bug-int-float.html
--min-version 1.0.4 character-set.html
--min-version 1.0.3 compare-loop-index-to-uniform.html --min-version 1.0.3 compare-loop-index-to-uniform.html
--min-version 1.0.3 complex-glsl-does-not-crash.html --min-version 1.0.3 complex-glsl-does-not-crash.html
--min-version 1.0.4 compound-assignment-type-combination.html --min-version 1.0.4 compound-assignment-type-combination.html
@ -47,6 +46,5 @@
--min-version 1.0.4 undefined-index-should-not-crash.html --min-version 1.0.4 undefined-index-should-not-crash.html
--min-version 1.0.3 uniforms-should-not-lose-values.html --min-version 1.0.3 uniforms-should-not-lose-values.html
--min-version 1.0.4 varying-arrays-should-not-be-reversed.html --min-version 1.0.4 varying-arrays-should-not-be-reversed.html
--min-version 1.0.4 vector-matrix-constructor-scalarization.html
--min-version 1.0.4 vector-scalar-arithmetic-inside-loop.html --min-version 1.0.4 vector-scalar-arithmetic-inside-loop.html
--min-version 1.0.4 vector-scalar-arithmetic-inside-loop-complex.html --min-version 1.0.4 vector-scalar-arithmetic-inside-loop-complex.html

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

@ -54,7 +54,7 @@ if (!gl) {
debug(""); debug("");
debug("Checking shader compilation and linking."); debug("Checking shader compilation and linking.");
checkCompilation(); checkCompilation()
} }
function checkCompilation() { function checkCompilation() {

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

@ -1,115 +0,0 @@
<!--
Copyright (c) 2020 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">
<title>Character Set</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/glsl-conformance-test.js"></script>
</head>
<body>
<div id="description"></div>
<div id="console"></div>
<canvas id="canvas" width="2" height="2"> </canvas>
<script>
"use strict";
// See http://crbug.com/1108588 for original failing case.
// Check "OpenGL Registry The OpenGL ES Shading Language"
// Section 3.2 Character Sets For more info
description("This test checks character set validation for glsl.");
debug("");
debug("Canvas.getContext");
let wtu = WebGLTestUtils;
let gl = wtu.create3DContext("canvas");
let consoleDiv = document.getElementById("console");
if (!gl) {
testFailed("context does not exist");
} else {
testPassed("context exists");
debug("");
debug("Checking shader character set validation and compilation");
runTest();
}
function testShaderSource(shaderSource, msg) {
if (!quietMode()) {
wtu.addShaderSource(consoleDiv, "test fragment shader", shaderSource);
}
let shader = gl.createShader(gl.FRAGMENT_SHADER);
if (shader == null) {
testFailed("*** Error: unable to create shader '" + shaderSource + "'");
return;
}
gl.shaderSource(shader, shaderSource);
wtu.glErrorShouldBe(gl, gl.NO_ERROR, msg);
}
function MUST(ifTruthy) {
return ifTruthy ? 'MUST' : 'MUST NOT';
}
function runTest() {
const BAD_STRINGS = [
'$',
'"',
'一些注释',
'#line 42 "foo.glsl"',
];
const TESTS = [
['in identifier', s => s, false],
['in comment', s => `// ${s}`, true, true],
['in ifdef-out', s => `#if 0 \n${s} \n#endif`, true],
['in ifdef-out #preproc', s => `#if 0 \n#${s} \n#endif`, true],
['in #preproc', s => `#${s}`, false],
['in comment after #define', s => `#define TEST // ${s}`, true], // Regression test for crbug.com/940865
];
const glsl_tests = [];
for (const s of BAD_STRINGS) {
for (const [where, template, validCompile] of TESTS) {
const st = template(s);
const src = `
precision mediump float;
${st}
void main() {
gl_FragColor = vec4(1, 0, 0, 1);
}`.trim();
testShaderSource(src, `shaderSource allows Out-of-charset string '${s}' ${where} until compilation.`);
glsl_tests.push(
{
fShaderSource: src,
fShaderSuccess: validCompile,
linkSuccess: validCompile,
passMsg: `Out-of-charset string '${s}' ${where} ${MUST(validCompile)} compile.`
}
);
}
}
GLSLConformanceTester.runTests(glsl_tests);
}
debug("");
var successfullyParsed = true;
</script>
</body>
</html>

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

@ -1,181 +0,0 @@
<!--
Copyright (c) 2021 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">
<title></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>
<!--
Original Shadertoy:
https://www.shadertoy.com/view/ttGyzh
float a = 0.; // bug
#define A 0. // ok
//#define A min(0.,iTime) // bug
#define r(a) mat2( cos( a + vec4(0,-1.5708,1.5708,0) ) ) // bug
//#define r(a) mat2( cos(a), -sin(a), sin(a), cos(a) ) // no bug
//#define r(a) cos(a),sin(a)) // no bug ( vec instead of mat )
//#define r(a) cos(a+vec2(0,-1.5708)) // no bug ( vec instead of mat )
vec2 c;
#define f(U,a) ( c = (U) * r(a) , sin(10.*c.x) )
void mainImage( out vec4 O, vec2 U )
{
U /= iResolution.xy;
O = U.y > .5
? vec4( f(U,a) , f(U*4.,a) , 0,0) // top
: vec4( f(U,A) , f(U*4.,A) , 0,0); // bottom
}
-->
<script id="vshader" type="x-shader/x-vertex">
attribute vec2 aPosition;
attribute vec2 aTexCoord;
varying vec2 vTexCoord;
void main(void) {
gl_Position = vec4(aPosition, 0.0, 1.0);
vTexCoord = aTexCoord;
}
</script>
<script id="fshader" type="x-shader/x-fragment">
precision mediump float;
varying vec2 vTexCoord;
float a = 0.;
#define A 0.
#define r(a) mat2( cos( a + vec4(0,-1.5708,1.5708,0) ) )
vec2 c;
#define f(U,a) ( c = (U) * r(a) , sin(10.*c.x) )
void main() {
vec2 U = vTexCoord;
gl_FragColor = U.y > .5
? vec4( f(U,a) , f(U*4.,a) , 0,1.0) // top
: vec4( f(U,A) , f(U*4.,A) , 0,1.0); // bottom
}
</script>
<script id="compileVShader" type="x-shader/x-vertex">
varying vec2 v_texcoord;
void main() {
v_texcoord = vec2(0.0, 0.0);
gl_Position = vec4(1.0, 0.0, 0.0, 1.0);
}
</script>
<script id="compileFShader" type="x-shader/x-fragment">
// From http://crbug.com/398694
precision mediump float;
uniform sampler2D s_texture;
uniform vec4 color_weights;
varying vec2 v_texcoord;
void main() {
gl_FragColor = color_weights * mat4(
vec4(texture2D(s_texture, v_texcoord).rgb, 1.0),
vec4(texture2D(s_texture, v_texcoord).rgb, 1.0),
vec4(texture2D(s_texture, v_texcoord).rgb, 1.0),
vec4(texture2D(s_texture, v_texcoord).rgb, 1.0));
}
</script>
</head>
<body>
<canvas id="example"></canvas>
<div id="description"></div>
<div id="console"></div>
<script>
"use strict";
debug("");
description("Vector and matrix constructor scalarization workaround (SH_SCALARIZE_VEC_AND_MAT_CONSTRUCTOR_ARGS) caused bugs");
debug('Regression test for <a href="http://crbug.com/1165751">crbug.com/1165751</a>');
// Note: Firefox reports that without this workaround, there are
// failures on at least Windows / Intel GPU / OpenGL on:
// conformance/glsl/constructors/glsl-construct-mat2.html
// https://searchfox.org/mozilla-central/source/dom/canvas/WebGLShaderValidator.cpp#63
// Chromium reported that
// conformance/glsl/misc/shader-struct-scope.html failed on macOS and
// on Linux AMD without this workaround enabled:
// http://crbug.com/angleproject/701
const wtu = WebGLTestUtils;
const canvas = document.getElementById("example");
const sz = canvas.width = canvas.height = 256;
const gl = wtu.create3DContext(canvas, undefined);
if (!gl) {
testFailed("WebGL context creation failed");
finishTest();
} else {
testPassed("WebGL context creation succeeded");
runDrawTest();
runCompileTest();
finishTest();
}
function runDrawTest() {
debug("Ensure that shader translation isn't broken by the vector and matrix constructor scalarization workaround");
let positionLocation = 0;
let texCoordLocation = 1;
wtu.setupUnitQuad(gl, positionLocation, texCoordLocation);
let program = wtu.setupProgram(gl, ["vshader", "fshader"],
["aPosition", "aTexCoord"],
[positionLocation, texCoordLocation], true);
if (!program) {
testFailed("Error compiling shaders");
return;
}
gl.useProgram(program);
// Buffers returned from setupQuad above, and ignored, are already bound.
wtu.drawUnitQuad(gl);
// Top and bottom halves should be roughly equal. Go through one
// horizontal scanline in the middle.
const compareHeight = sz / 4;
let pixelValue = new Uint8Array(4);
let allEqual = true;
// Empirically found that tolerance between the top and bottom
// needs to be up to roughly 8 on some platforms.
const tolerance = 8;
let tempBuf = new Uint8Array(4);
// Step over some pixels to spew slightly fewer comparison messages.
for (let x = 0; x < sz; x += 4) {
gl.readPixels(x, compareHeight, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, pixelValue);
wtu.checkCanvasRect(gl, x, sz - compareHeight, 1, 1, pixelValue, undefined, tolerance, tempBuf);
}
}
function runCompileTest() {
debug("Running compilation test");
let program = wtu.setupProgram(gl, ["compileVShader", "compileFShader"], [], [], true);
if (program) {
testPassed("Shader previously requiring SH_SCALARIZE_VEC_AND_MAT_CONSTRUCTOR_ARGS compiled successfully");
} else {
testFailed("Shader previously requiring SH_SCALARIZE_VEC_AND_MAT_CONSTRUCTOR_ARGS failed to compile");
}
}
</script>
</body>
</html>

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

@ -49,5 +49,6 @@ void main()
GLSLConformanceTester.runRenderTest(); GLSLConformanceTester.runRenderTest();
var successfullyParsed = true; var successfullyParsed = true;
</script> </script>
<script src="../../../js/js-test-post.js"></script>
</body> </body>
</html> </html>

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

@ -38,6 +38,7 @@ shader-with-clipvertex.vert.html
--min-version 1.0.2 shader-with-conditional-scoping-negative.html --min-version 1.0.2 shader-with-conditional-scoping-negative.html
shader-with-default-precision.frag.html shader-with-default-precision.frag.html
shader-with-default-precision.vert.html shader-with-default-precision.vert.html
--max-version 1.9.9 shader-with-define-line-continuation.frag.html
shader-with-dfdx-no-ext.frag.html shader-with-dfdx-no-ext.frag.html
shader-with-dfdx.frag.html shader-with-dfdx.frag.html
--min-version 1.0.2 shader-with-do-loop.html --min-version 1.0.2 shader-with-do-loop.html

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

@ -18,35 +18,20 @@ found in the LICENSE.txt file.
<body> <body>
<div id="description"></div> <div id="description"></div>
<div id="console"></div> <div id="console"></div>
<script id="vertexShader" type="text/plain"> <script id="vertexShader" type="text/something-not-javascript">
Loading... // Non ascii comments in source should succeed
// これはASCIIではないです。
//    
/*
*    
*/
#define TEST 1 // <20>スs<EFBDBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ス@<40>スh<EFBDBD><EFBFBD><EFBFBD>ス@<40>スm<EFBDBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ス@<40>ス`<60>スr<EFBDBD>スb<EFBDBD>スh<EFBDBD>スh
void main() {
gl_Position = vec4(1,1,1,1); // <20>スs<EFBDBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ス@<40>スh<EFBDBD><EFBFBD><EFBFBD>ス@<40>スm<EFBDBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ス@<40>ス`<60>スr<EFBDBD>スb<EFBDBD>スh<EFBDBD>スh
} // <20>スs<EFBDBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ス@<40>スh<EFBDBD><EFBFBD><EFBFBD>ス@<40>スm<EFBDBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ス@<40>ス`<60>スr<EFBDBD>スb<EFBDBD>スh<EFBDBD>スh
</script> </script>
<script> <script>
"use strict"; "use strict";
// Via `[].map.call(str, x => x.codePointAt(0));`
let a = [12371,12428,12399,65313,65331,65315,65321,65321,12391,12399,12394,12356,12391,12377,12290];
let b = [65332,65352,65353,65363,12288,65321,65363,12288,65326,65359,65364,12288,65313,65331,65315,65321,65321];
a = String.fromCodePoint(...a);
b = String.fromCodePoint(...b);
// -
vertexShader.textContent = `
// Non ascii comments in source should succeed
// ${a}
// ${b}
/*
* ${b}
*/
#define TEST 1 // ${b}
void main() {
gl_Position = vec4(1,1,1,1); // ${b}
} // ${b}
`;
// -
GLSLConformanceTester.runTest(); GLSLConformanceTester.runTest();
var successfullyParsed = true; var successfullyParsed = true;
</script> </script>

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

@ -18,35 +18,18 @@ found in the LICENSE.txt file.
<body> <body>
<div id="description"></div> <div id="description"></div>
<div id="console"></div> <div id="console"></div>
<script id="vertexShader" type="text/plain"> <script id="vertexShader" type="text/something-not-javascript">
Loading...
</script>
<script>
"use strict";
// Via `[].map.call(str, x => x.codePointAt(0));`
let a = [12371,12428,12399,65313,65331,65315,65321,65321,12391,12399,12394,12356,12391,12377,12290];
let b = [65332,65352,65353,65363,12288,65321,65363,12288,65326,65359,65364,12288,65313,65331,65315,65321,65321];
let c = [65326,65359,65364,65313,65331,65315,65321,65321];
a = String.fromCodePoint(...a);
b = String.fromCodePoint(...b);
c = String.fromCodePoint(...c);
// -
vertexShader.textContent = `
// Non ascii data in source should fail // Non ascii data in source should fail
// See GLSL ES Spec 1.0.17 section 3.1 and 3.2 // See GLSL ES Spec 1.0.17 section 3.1 and 3.2
// ${a} // これはASCIIではないです。
// ${b} //    
uniform mat4 ${c}; uniform mat4 ;
void main() { void main() {
gl_Position = vec4(1,1,1,1); gl_Position = vec4(1,1,1,1);
} }
`; </script>
<script>
// - "use strict";
GLSLConformanceTester.runTest(); GLSLConformanceTester.runTest();
var successfullyParsed = true; var successfullyParsed = true;
</script> </script>

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

@ -0,0 +1,37 @@
<!--
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">
<title>WebGL GLSL Conformance Tests</title>
<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
<link rel="stylesheet" href="../../../resources/glsl-feature-tests.css"/>
<script src="../../../js/js-test-pre.js"></script>
<script src="../../../js/webgl-test-utils.js"></script>
<script src="../../../js/glsl-conformance-test.js"></script>
</head>
<body>
<div id="description"></div>
<div id="console"></div>
<script id="fragmentShader" type="text/something-not-javascript">
// fragment shader that uses line continuation macro should fail
#define foo this \
is a test
precision mediump float;
void main()
{
gl_FragColor = vec4(0.0,0.0,0.0,1.0);
}
</script>
<script>
"use strict";
GLSLConformanceTester.runTest();
var successfullyParsed = true;
</script>
</body>
</html>

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

@ -39,13 +39,7 @@ void main()
"use strict"; "use strict";
/* /*
This test previously concluded that an attribute in a vertex shader GLSL 1.017 section 4.2.6
would conflict across shaders with a uniform of the same name in the
fragment shader, based on the following sections of the GLSL ES 1.0.17
specification:
---
Section 4.2.6
... ...
@ -62,15 +56,16 @@ Attribute variables are required to have global scope
Section 4.3.4 Section 4.3.4
The uniform qualifier is used to declare global variables The uniform qualifier is used to declare global variables
---
GLSL ES 3.00 later confirmed that pipeline stages have distinct QED: If both uniforms and attributes are in the global namespace they
namespaces. The OpenGL ES working group confirmed in discussions conflict across shaders
https://github.com/KhronosGroup/WebGL/issues/3201 that this was the
intended behavior for GLSL ES 1.00.
For this reason, this test asserts that such usage does not generate a Note: This was brought up on the OpenGL ES working group and confirmed
conflict. that the spec required these conflicts to fail to link.
Though most drivers allow this to work, some drivers to do no therefore
WebGL implementation must enforce this restriction to provide consistent
behavior.
*/ */
GLSLConformanceTester.runTests([ GLSLConformanceTester.runTests([
@ -78,8 +73,8 @@ GLSLConformanceTester.runTests([
vShaderSuccess: true, vShaderSuccess: true,
fShaderId: 'fragmentShader', fShaderId: 'fragmentShader',
fShaderSuccess: true, fShaderSuccess: true,
linkSuccess: true, linkSuccess: false,
passMsg: 'using the same name for a vertex shader attribute and fragment shader uniform should succeed' passMsg: 'shaders with conflicting uniform/attribute names should fail'
}, },
]); ]);
var successfullyParsed = true; var successfullyParsed = true;

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

@ -126,15 +126,12 @@ for (var i = 0; i < invalidSet.length; ++i) {
// Backslash as line-continuation is allowed in WebGL 2.0. // Backslash as line-continuation is allowed in WebGL 2.0.
if (contextVersion > 1 && invalidSet[i] == '\\') if (contextVersion > 1 && invalidSet[i] == '\\')
continue; continue;
// With recent specification changes from
// https://github.com/KhronosGroup/WebGL/pull/3206 , shaderSource no
// longer generates INVALID_VALUE.
var validShaderSource = generateShaderSource(undefined, invalidSet[i]); var validShaderSource = generateShaderSource(undefined, invalidSet[i]);
context.shaderSource(vShader, validShaderSource); context.shaderSource(vShader, validShaderSource);
shouldBe("context.getError()", "context.NO_ERROR"); shouldBe("context.getError()", "context.NO_ERROR");
var invalidShaderSource = generateShaderSource(invalidSet[i], undefined); var invalidShaderSource = generateShaderSource(invalidSet[i], undefined);
context.shaderSource(vShader, invalidShaderSource); context.shaderSource(vShader, invalidShaderSource);
shouldBe("context.getError()", "context.NO_ERROR"); shouldBe("context.getError()", "context.INVALID_VALUE");
} }
debug(""); debug("");

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

@ -128,209 +128,6 @@ shouldBeTrue('shaderPrecisionFormat.rangeMin == shaderPrecisionFormat2.rangeMin'
shouldBeTrue('shaderPrecisionFormat.rangeMax == shaderPrecisionFormat2.rangeMax'); shouldBeTrue('shaderPrecisionFormat.rangeMax == shaderPrecisionFormat2.rangeMax');
shouldBeTrue('shaderPrecisionFormat.precision == shaderPrecisionFormat2.precision'); shouldBeTrue('shaderPrecisionFormat.precision == shaderPrecisionFormat2.precision');
debug("");
debug("Test that specified precision matches rendering results");
debug("");
function testRenderPrecisionSetup(gl, shaderPair) {
const program = wtu.setupProgram(gl, shaderPair);
// Create a buffer and setup an attribute.
// We wouldn't need this except for a bug in Safari and arguably
// this should be removed from the test but we can't test the test itself
// without until the bug is fixed.
// see https://bugs.webkit.org/show_bug.cgi?id=197592
{
gl.bindBuffer(gl.ARRAY_BUFFER, gl.createBuffer());
gl.bufferData(gl.ARRAY_BUFFER, 1, gl.STATIC_DRAW);
const loc = gl.getAttribLocation(program, 'position');
gl.enableVertexAttribArray(loc);
gl.vertexAttribPointer(loc, 1, gl.UNSIGNED_BYTE, false, 0, 0);
}
gl.useProgram(program);
return program;
}
function testRenderPrecision(gl, shaderType, type, precision, expected, msg) {
gl.clear(gl.COLOR_BUFFER_BIT);
gl.drawArrays(gl.POINTS, 0, 1);
const pixel = new Uint8Array(4);
gl.readPixels(0, 0, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, pixel);
wtu.checkCanvasRect(gl, 0, 0, 1, 1, expected, msg, 5);
}
function testRenderPrecisionFloat(gl, precisionEnum, precision) {
function test(gl, shaderPair, shaderType) {
const format = gl.getShaderPrecisionFormat(shaderType, precisionEnum);
const value = 2 ** format.precision - 1;
const length = v => Math.sqrt(v.reduce((sum, v) => sum + v * v, 0));
const normalize = (v) => {
const l = length(v);
return v.map(v => v / l);
};
const input = [Math.sqrt(value), Math.sqrt(value), Math.sqrt(value)];
const expected = [...normalize(input).map(v => (v * 0.5 + 0.5) * 255 | 0), 255];
const msg = `${wtu.glEnumToString(gl, shaderType)}: ${precision} float precision: ${format.precision}, rangeMin: ${format.rangeMin}, rangeMax: ${format.rangeMax}`;
const program = testRenderPrecisionSetup(gl, shaderPair);
const vLocation = gl.getUniformLocation(program, 'v');
gl.uniform3fv(vLocation, input);
testRenderPrecision(gl, shaderType, 'float', precision, expected, msg);
}
{
const vs = `
attribute vec4 position;
uniform ${precision} vec3 v;
varying ${precision} vec4 v_result;
void main() {
gl_Position = position;
gl_PointSize = 1.0;
v_result = vec4(normalize(v) * 0.5 + 0.5, 1);
}
`;
const fs = `
precision ${precision} float;
varying ${precision} vec4 v_result;
void main() {
gl_FragColor = v_result;
}
`;
test(gl, [vs, fs], gl.VERTEX_SHADER);
}
{
const vs = `
attribute vec4 position;
void main() {
gl_Position = position;
gl_PointSize = 1.0;
}
`;
const fs = `
precision ${precision} float;
uniform ${precision} vec3 v;
void main() {
gl_FragColor = vec4(normalize(v) * 0.5 + 0.5, 1);
}
`;
test(gl, [vs, fs], gl.FRAGMENT_SHADER);
}
}
function testRenderPrecisionInt(gl, precisionEnum, precision) {
function test(gl, shaderPair, shaderType) {
const format = gl.getShaderPrecisionFormat(shaderType, precisionEnum);
const value = 1 << (format.rangeMax - 1);
const input = [value, value, value, value];
const expected = [255, 255, 255, 255];
const msg = `${wtu.glEnumToString(gl, shaderType)}: ${precision} int precision: ${format.precision}, rangeMin: ${format.rangeMin}, rangeMax: ${format.rangeMax}`;
const program = testRenderPrecisionSetup(gl, shaderPair);
gl.uniform1i(gl.getUniformLocation(program, 'v'), value);
gl.uniform1f(gl.getUniformLocation(program, 'f'), value);
testRenderPrecision(gl, shaderType, 'int', precision, expected, msg);
}
{
const vs = `
attribute vec4 position;
uniform ${precision} int v;
uniform highp float f;
varying vec4 v_result;
void main() {
gl_Position = position;
gl_PointSize = 1.0;
float diff = abs(float(v) - f);
bool pass = diff < 1.0;
v_result = vec4(pass);
}
`;
const fs = `
precision mediump float;
varying vec4 v_result;
void main() {
gl_FragColor = v_result;
}
`;
test(gl, [vs, fs], gl.VERTEX_SHADER);
}
{
const vs = `
attribute vec4 position;
void main() {
gl_Position = position;
gl_PointSize = 1.0;
}
`;
const fs = `
precision ${precision} float;
uniform ${precision} int v;
uniform mediump float f;
void main() {
mediump float diff = abs(float(v) - f);
bool pass = diff < 1.0;
gl_FragColor = vec4(pass);
}
`;
test(gl, [vs, fs], gl.FRAGMENT_SHADER);
}
}
// because the canvas can be 16 bit IIRC
const fb = gl.createFramebuffer(gl.FRAMEBUFFER);
gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
const tex = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, tex);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
gl.framebufferTexture2D(
gl.FRAMEBUFFER,
gl.COLOR_ATTACHMENT0,
gl.TEXTURE_2D,
tex,
0);
gl.viewport(0, 0, 1, 1);
{
testRenderPrecisionFloat(gl, gl.LOW_FLOAT, 'lowp');
testRenderPrecisionFloat(gl, gl.MEDIUM_FLOAT, 'mediump');
const format = gl.getShaderPrecisionFormat(gl.FRAGMENT_SHADER, gl.HIGH_FLOAT);
if (format.precision !== 0) {
testRenderPrecisionFloat(gl, gl.HIGH_FLOAT, 'highp');
}
}
{
testRenderPrecisionInt(gl, gl.LOW_INT, 'lowp');
testRenderPrecisionInt(gl, gl.MEDIUM_INT, 'mediump');
const format = gl.getShaderPrecisionFormat(gl.FRAGMENT_SHADER, gl.HIGH_INT);
if (format.rangeMax !== 0) {
testRenderPrecisionInt(gl, gl.HIGH_INT, 'highp');
}
}
finishTest(); finishTest();
</script> </script>

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

@ -178,75 +178,6 @@ gl.deleteTexture(tex);
gl.finish(); gl.finish();
wtu.glErrorShouldBe(gl, gl.NO_ERROR); wtu.glErrorShouldBe(gl, gl.NO_ERROR);
debug("");
debug("Reading an uninitialized portion of a texture (copyTexSubImage2D) should succeed with all bytes set to 0.");
var tex = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, tex);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
wtu.glErrorShouldBe(gl, gl.NO_ERROR);
var fbo = gl.createFramebuffer();
gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
var rbo = gl.createRenderbuffer();
gl.bindRenderbuffer(gl.RENDERBUFFER, rbo);
var fboWidth = 16;
var fboHeight = 16;
gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA4, fboWidth, fboHeight);
gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, rbo);
shouldBe("gl.checkFramebufferStatus(gl.FRAMEBUFFER)", "gl.FRAMEBUFFER_COMPLETE");
gl.clearColor(1.0, 0.0, 0.0, 1.0);
gl.clear(gl.COLOR_BUFFER_BIT);
wtu.glErrorShouldBe(gl, gl.NO_ERROR);
gl.copyTexSubImage2D(gl.TEXTURE_2D, 0, 0, 0, 0, 0, width, height);
checkNonZeroPixels(tex, width, height, 0, 0, fboWidth, fboHeight, 255, 0, 0, 255);
gl.deleteTexture(tex);
gl.finish();
wtu.glErrorShouldBe(gl, gl.NO_ERROR);
debug("");
debug("Reading an uninitialized portion of a texture (copyTexSubImage2D with negative x and y) should succeed with all bytes set to 0.");
var tex = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, tex);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
wtu.glErrorShouldBe(gl, gl.NO_ERROR);
var fbo = gl.createFramebuffer();
gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
var rbo = gl.createRenderbuffer();
gl.bindRenderbuffer(gl.RENDERBUFFER, rbo);
var fboWidth = 16;
var fboHeight = 16;
gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA4, fboWidth, fboHeight);
gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, rbo);
shouldBe("gl.checkFramebufferStatus(gl.FRAMEBUFFER)", "gl.FRAMEBUFFER_COMPLETE");
gl.clearColor(1.0, 0.0, 0.0, 1.0);
gl.clear(gl.COLOR_BUFFER_BIT);
wtu.glErrorShouldBe(gl, gl.NO_ERROR);
var x = -8;
var y = -8;
gl.copyTexSubImage2D(gl.TEXTURE_2D, 0, 0, 0, x, y, width, height);
checkNonZeroPixels(tex, width, height, -x, -y, fboWidth, fboHeight, 255, 0, 0, 255);
gl.deleteTexture(tex);
gl.finish();
wtu.glErrorShouldBe(gl, gl.NO_ERROR);
debug("");
debug("Reading an uninitialized portion of a texture (copyTexSubImage2D from WebGL internal fbo) should succeed with all bytes set to 0.");
var tex = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, tex);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
wtu.glErrorShouldBe(gl, gl.NO_ERROR);
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
gl.clearColor(0.0, 1.0, 0.0, 0.0);
gl.clear(gl.COLOR_BUFFER_BIT);
wtu.glErrorShouldBe(gl, gl.NO_ERROR);
gl.copyTexSubImage2D(gl.TEXTURE_2D, 0, 0, 0, 0, 0, width, height);
checkNonZeroPixels(tex, width, height, 0, 0, canvas.width, canvas.height, 0, 255, 0, 0);
gl.deleteTexture(tex);
gl.finish();
wtu.glErrorShouldBe(gl, gl.NO_ERROR);
//TODO: uninitialized vertex array buffer //TODO: uninitialized vertex array buffer
//TODO: uninitialized vertex elements buffer //TODO: uninitialized vertex elements buffer
//TODO: uninitialized framebuffer? (implementations would need to do a GL clear at first binding?) //TODO: uninitialized framebuffer? (implementations would need to do a GL clear at first binding?)

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

@ -11,10 +11,6 @@ found in the LICENSE.txt file.
<script type="application/javascript" src="../unit.js"></script> <script type="application/javascript" src="../unit.js"></script>
<script type="application/javascript" src="../util.js"></script> <script type="application/javascript" src="../util.js"></script>
<script type="application/javascript" src="../../../js/webgl-test-utils.js"></script> <script type="application/javascript" src="../../../js/webgl-test-utils.js"></script>
</head><body>
<canvas id="gl" width="16" height="16"></canvas>
<canvas id="c" width="128" height="128"></canvas>
<img id="i">
<script type="application/javascript"> <script type="application/javascript">
var wtu = WebGLTestUtils; var wtu = WebGLTestUtils;
var defaultImgUrl = "https://get.webgl.org/conformance-resources/opengl_logo.jpg"; var defaultImgUrl = "https://get.webgl.org/conformance-resources/opengl_logo.jpg";
@ -96,18 +92,12 @@ Tests.testReadPixelsSOPCanvas = function(gl) {
} }
Tests.endUnit = function(gl) { Tests.endUnit = function(gl) {
}; }
(async function() { wtu.setupImageForCrossOriginTest("#i", defaultImgUrl, localImgUrl, initTests);
const img = document.getElementById('i');
try {
await wtu.awaitOrTimeout(wtu.loadCrossOriginImage(img, defaultImgUrl, localImgUrl));
} catch (e) {
testFailed(`Image setup failed (${e}).`);
finishTest();
return;
}
initTests();
})();
</script> </script>
</head><body>
<canvas id="gl" width="16" height="16"></canvas>
<canvas id="c" width="128" height="128"></canvas>
<img id="i">
</body></html> </body></html>

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

@ -133,14 +133,23 @@ Tests.testTexImage2DNonSOP = function(gl) {
Tests.endUnit = function(gl) { Tests.endUnit = function(gl) {
}; };
(async function() { async function setupNonSOPImage() {
const img = document.getElementById('i2'); const img = document.getElementById('i2');
const url = wtu.chooseUrlForCrossOriginImage(defaultImgUrl, localImgUrl);
img.src = url;
await img.decode();
}
async function throwOnTimeout(ms) {
await wtu.awaitTimeout(ms);
throw 'timeout';
}
(async function() {
try { try {
await wtu.awaitOrTimeout(wtu.loadCrossOriginImage(img, defaultImgUrl, localImgUrl)); await Promise.race([setupNonSOPImage(), throwOnTimeout(1000)]);
} catch (e) { } catch (e) {
testFailed(`Image setup failed (${e}).`); console.log(`Image setup failed (${e}), running tests anyway.`);
finishTest();
return;
} }
initTests(); initTests();
})(); })();

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

@ -143,16 +143,25 @@ Tests.testTexImage2DNonSOP = function(gl) {
} }
Tests.endUnit = function(gl) { Tests.endUnit = function(gl) {
}; }
async function setupNonSOPImage() {
const img = document.getElementById('i2');
const url = wtu.chooseUrlForCrossOriginImage(defaultImgUrl, localImgUrl);
img.src = url;
await img.decode();
}
async function throwOnTimeout(ms) {
await wtu.awaitTimeout(ms);
throw 'timeout';
}
(async function() { (async function() {
const img = document.getElementById('i2');
try { try {
await wtu.awaitOrTimeout(wtu.loadCrossOriginImage(img, defaultImgUrl, localImgUrl)); await Promise.race([setupNonSOPImage(), throwOnTimeout(1000)]);
} catch (e) { } catch (e) {
testFailed(`Image setup failed (${e}).`); console.log(`Image setup failed (${e}), running tests anyway.`);
finishTest();
return;
} }
initTests(); initTests();
})(); })();

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

@ -33,7 +33,7 @@ function compareImages(refData, tstData, width, height, diff) {
return true; return true;
} }
// TODO: Implement crazy check that's used in OpenGL ES 2.0 conformance tests. // TODO: Implement check that's used in OpenGL ES 2.0 conformance tests.
// NOTE: on Desktop things seem to be working. Maybe the more complex check // NOTE: on Desktop things seem to be working. Maybe the more complex check
// is needed for embedded systems? // is needed for embedded systems?
return false; return false;

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

@ -24,7 +24,6 @@ found in the LICENSE.txt file.
description("Checks that ReadPixels works as expected."); description("Checks that ReadPixels works as expected.");
var wtu = WebGLTestUtils; var wtu = WebGLTestUtils;
let gl;
debug("<h1>antialias = false</h1>") debug("<h1>antialias = false</h1>")
runTest(document.getElementById("example"), false); runTest(document.getElementById("example"), false);
@ -36,7 +35,7 @@ var actual;
var expected; var expected;
function runTest(canvas, antialias) { function runTest(canvas, antialias) {
gl = wtu.create3DContext(canvas, {antialias: antialias}); var gl = wtu.create3DContext(canvas, {antialias: antialias});
var contextVersion = wtu.getDefault3DContextVersion(); var contextVersion = wtu.getDefault3DContextVersion();
var width = 2; var width = 2;
@ -180,10 +179,17 @@ function runTest(canvas, antialias) {
wtu.glErrorShouldBe(gl, [gl.INVALID_ENUM, gl.INVALID_OPERATION], "Should not be able to read as " + wtu.glEnumToString(gl, type)); 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,
const combinations = [ type: gl.UNSIGNED_BYTE,
dest: new Uint8Array(4),
},
{
format: gl.RGB,
type: gl.UNSIGNED_BYTE,
dest: new Uint8Array(3),
},
{ {
format: gl.RGB, format: gl.RGB,
type: gl.UNSIGNED_SHORT_5_6_5, type: gl.UNSIGNED_SHORT_5_6_5,
@ -199,113 +205,37 @@ function runTest(canvas, antialias) {
type: gl.UNSIGNED_SHORT_4_4_4_4, type: gl.UNSIGNED_SHORT_4_4_4_4,
dest: new Uint16Array(1), dest: new Uint16Array(1),
}, },
];
const FORMATS = [
{ {
format: gl.RGBA,
channels: 4,
}, {
format: gl.RGB,
channels: 3,
}, {
format: gl.LUMINANCE_ALPHA,
channels: 2,
}, {
format: gl.ALPHA, format: gl.ALPHA,
channels: 1, type: gl.UNSIGNED_BYTE,
}, { dest: new Uint8Array(1),
format: gl.LUMINANCE, }
channels: 3,
},
]; ];
if (contextVersion >= 2) { if (contextVersion > 1) {
FORMATS.push( combinations = combinations.concat([
{ {
format: gl.RED, format: gl.RED,
channels: 1,
}, {
format: gl.RG,
channels: 1,
}, {
format: gl.RGBA_INTEGER,
channels: 4,
}, {
format: gl.RGB_INTEGER,
channels: 3,
}, {
format: gl.RG_INTEGER,
channels: 2,
}, {
format: gl.RED_INTEGER,
channels: 1,
}
);
}
// -
const TYPES = [
{
type: gl.UNSIGNED_BYTE, type: gl.UNSIGNED_BYTE,
ctor: Uint8Array, dest: new Uint8Array(1),
}, { },
type: gl.BYTE, {
ctor: Int8Array, format: gl.RGBA_INTEGER,
}, {
type: gl.UNSIGNED_SHORT,
ctor: Uint16Array,
}, {
type: gl.SHORT,
ctor: Int16Array,
}, {
type: gl.UNSIGNED_INT, type: gl.UNSIGNED_INT,
ctor: Uint32Array, dest: new Uint32Array(4),
}, { },
{
format: gl.RGBA_INTEGER,
type: gl.INT, type: gl.INT,
ctor: Int32Array, dest: new Int32Array(4),
}, {
type: gl.FLOAT,
ctor: Float32Array,
} }
]; ]);
if (contextVersion >= 2) {
TYPES.push(
{
type: gl.HALF_FLOAT,
ctor: Uint16Array,
} }
);
}
const ext = gl.getExtension('OES_texture_half_float');
if (ext) {
TYPES.push(
{
type: ext.HALF_FLOAT_OES,
ctor: Uint16Array,
}
);
}
for (const t of TYPES) {
for (const f of FORMATS) {
const desc = Object.assign({}, f, t);
desc.dest = new desc.ctor(desc.channels);
combinations.push(desc);
}
}
// -
debug(""); debug("");
debug("check invalid combinations of format/type"); debug("check invalid combinations of format/type");
var implFormat = gl.getParameter(gl.IMPLEMENTATION_COLOR_READ_FORMAT); var implFormat = gl.getParameter(gl.IMPLEMENTATION_COLOR_READ_FORMAT);
var implType = gl.getParameter(gl.IMPLEMENTATION_COLOR_READ_TYPE); var implType = gl.getParameter(gl.IMPLEMENTATION_COLOR_READ_TYPE);
debug("IMPLEMENTATION_COLOR_READ_FORMAT: " + wtu.glEnumToString(gl, implFormat));
debug("IMPLEMENTATION_COLOR_READ_TYPE: " + wtu.glEnumToString(gl, implType));
for (var tt = 0; tt < combinations.length; ++ tt) { for (var tt = 0; tt < combinations.length; ++ tt) {
var info = combinations[tt]; var info = combinations[tt];
@ -323,7 +253,7 @@ function runTest(canvas, antialias) {
" / " + wtu.glEnumToString(gl, type)); " / " + wtu.glEnumToString(gl, type));
} else { } else {
wtu.glErrorShouldBe( wtu.glErrorShouldBe(
gl, [gl.INVALID_OPERATION, gl.INVALID_ENUM], gl, gl.INVALID_OPERATION,
"Should not be able to read as " + wtu.glEnumToString(gl, format) + "Should not be able to read as " + wtu.glEnumToString(gl, format) +
" / " + wtu.glEnumToString(gl, type)); " / " + wtu.glEnumToString(gl, type));
} }
@ -405,22 +335,6 @@ function runTest(canvas, antialias) {
"color pixel at 0, 0 should be [0, 255, 0, 255], was " + "color pixel at 0, 0 should be [0, 255, 0, 255], was " +
[buf[0], buf[1], buf[2], buf[3]]); [buf[0], buf[1], buf[2], buf[3]]);
} }
const validDatas = [
`new Uint8Array(4)`,
`new Uint8Array(new ArrayBuffer(4))`,
`new Uint8ClampedArray(4)`,
`new Uint8ClampedArray(new ArrayBuffer(4))`,
];
if (window.SharedArrayBuffer) {
validDatas.push(
`new Uint8Array(new SharedArrayBuffer(4))`,
`new Uint8ClampedArray(new SharedArrayBuffer(4))`
);
}
for (const x of validDatas) {
shouldNotThrow(`gl.readPixels(0, 0, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, ${x});`);
}
} }
} }
</script> </script>

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

@ -4,12 +4,12 @@ Use of this source code is governed by an MIT-style license that can be
found in the LICENSE.txt file. found in the LICENSE.txt file.
--> -->
<!--
This bug would occur after the app would render several times with the This bug would occur after the app would render several times with the
same vertex attributes and buffers, but using a different start offset. same vertex attributes and buffers, but using a different start offset.
One of the buffers would likely have to be DYNAMIC. One of the buffers would likely have to be DYNAMIC.
See http://anglebug.com/1327 and http://crbug.com/594509 See http://anglebug.com/1327 and http://crbug.com/594509
--> -->
<!DOCTYPE html> <!DOCTYPE html>

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

@ -126,7 +126,6 @@ function runTest()
debug('Polygon offset factor of 0.1 should alter order of slanted polygons'); debug('Polygon offset factor of 0.1 should alter order of slanted polygons');
clear(gl, red, 1.0); clear(gl, red, 1.0);
gl.polygonOffset(0, 0);
draw(gl, slantedSquare, colLoc, green); draw(gl, slantedSquare, colLoc, green);
gl.polygonOffset(0.1, 0); gl.polygonOffset(0.1, 0);
draw(gl, slantedSquare, colLoc, blue); draw(gl, slantedSquare, colLoc, blue);
@ -134,7 +133,6 @@ function runTest()
debug('Polygon offset factor of 0.1 should not alter order of flat polygons'); debug('Polygon offset factor of 0.1 should not alter order of flat polygons');
clear(gl, red, 1.0); clear(gl, red, 1.0);
gl.polygonOffset(0, 0);
draw(gl, flatSquare, colLoc, blue); draw(gl, flatSquare, colLoc, blue);
gl.polygonOffset(0.1, 0); gl.polygonOffset(0.1, 0);
draw(gl, flatSquare, colLoc, green); draw(gl, flatSquare, colLoc, green);

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

@ -1,4 +1,3 @@
--min-version 1.0.4 fb-attach-implicit-target-assignment.html
gl-enable-enum-test.html gl-enable-enum-test.html
--max-version 1.9.9 gl-enum-tests.html --max-version 1.9.9 gl-enum-tests.html
gl-get-calls.html gl-get-calls.html

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

@ -1,94 +0,0 @@
<!--
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'>
<title>WebGL gl calls Conformance Tests</title>
<link rel='stylesheet' href='../../resources/js-test-style.css'/>
<script src='../../js/js-test-pre.js'></script>
<script src='../../js/webgl-test-utils.js'></script>
</head>
<body>
<div id='description'></div>
<div id='console'></div>
<canvas id='canvas' width='2' height='2'> </canvas>
<script>
'use strict';
description('Test implicit target assignment during FB attachment');
const wtu = WebGLTestUtils;
const gl = wtu.create3DContext('canvas');
let fb, rb, tex;
(() => {
if (!gl) {
testFailed('context does not exist');
return;
}
fb = gl.createFramebuffer();
gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
wtu.glErrorShouldBe(gl, 0, 'No errors');
// -
debug('');
debug('framebufferRenderbuffer');
rb = gl.createRenderbuffer();
shouldBe('gl.isRenderbuffer(rb)', 'false');
gl.bindRenderbuffer(gl.RENDERBUFFER, rb);
shouldBe('gl.isRenderbuffer(rb)', 'true');
rb = gl.createRenderbuffer();
shouldBe('gl.isRenderbuffer(rb)', 'false');
gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, rb);
wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, 'framebufferRenderbuffer must be preceeded by some bindRenderbuffer');
shouldBe('gl.isRenderbuffer(rb)', 'false');
wtu.glErrorShouldBe(gl, 0, 'No errors');
// -
debug('');
debug('framebufferTexture2D');
tex = gl.createTexture();
shouldBe('gl.isTexture(tex)', 'false');
gl.bindTexture(gl.TEXTURE_2D, tex);
shouldBe('gl.isTexture(tex)', 'true');
tex = gl.createTexture();
shouldBe('gl.isTexture(tex)', 'false');
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex, 0);
// https://bugzilla.mozilla.org/show_bug.cgi?id=1636524 :
wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, 'framebufferTexture2D must be preceeded by some bindTexture');
shouldBe('gl.isTexture(tex)', 'false');
gl.bindTexture(gl.TEXTURE_CUBE_MAP, tex);
wtu.glErrorShouldBe(gl, 0, 'No errors after bindTexture');
tex = gl.createTexture();
shouldBe('gl.isTexture(tex)', 'false');
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_CUBE_MAP_POSITIVE_X, tex, 0);
wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, 'framebufferTexture2D must be preceeded by some bindTexture');
shouldBe('gl.isTexture(tex)', 'false');
gl.bindTexture(gl.TEXTURE_2D, tex);
wtu.glErrorShouldBe(gl, 0, 'No errors after bindTexture');
})();
debug('');
var successfullyParsed = true;
</script>
<script src='../../js/js-test-post.js'></script>
</body>
</html>

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

@ -1,5 +1,5 @@
--min-version 1.0.4 canvas-teximage-after-multiple-drawimages.html --min-version 1.0.4 canvas-teximage-after-multiple-drawimages.html
--max-version 1.9.9 compressed-tex-image.html compressed-tex-image.html
copy-tex-image-and-sub-image-2d.html copy-tex-image-and-sub-image-2d.html
--min-version 1.0.2 copy-tex-image-2d-formats.html --min-version 1.0.2 copy-tex-image-2d-formats.html
--min-version 1.0.4 copy-tex-image-crash.html --min-version 1.0.4 copy-tex-image-crash.html
@ -8,11 +8,9 @@ copy-tex-image-and-sub-image-2d.html
--min-version 1.0.4 cube-incomplete-fbo.html --min-version 1.0.4 cube-incomplete-fbo.html
--min-version 1.0.4 cube-map-uploads-out-of-order.html --min-version 1.0.4 cube-map-uploads-out-of-order.html
--min-version 1.0.3 default-texture.html --min-version 1.0.3 default-texture.html
--min-version 1.0.4 exif-orientation.html
--min-version 1.0.2 --max-version 1.9.9 gl-get-tex-parameter.html --min-version 1.0.2 --max-version 1.9.9 gl-get-tex-parameter.html
gl-pixelstorei.html gl-pixelstorei.html
gl-teximage.html gl-teximage.html
--min-version 1.0.2 mipmap-fbo.html
origin-clean-conformance.html origin-clean-conformance.html
--min-version 1.0.4 origin-clean-conformance-offscreencanvas.html --min-version 1.0.4 origin-clean-conformance-offscreencanvas.html
tex-image-and-sub-image-2d-with-array-buffer-view.html tex-image-and-sub-image-2d-with-array-buffer-view.html
@ -31,14 +29,11 @@ texture-active-bind.html
--min-version 1.0.2 texture-attachment-formats.html --min-version 1.0.2 texture-attachment-formats.html
--min-version 1.0.2 texture-clear.html --min-version 1.0.2 texture-clear.html
texture-complete.html texture-complete.html
--min-version 1.0.4 texture-copying-and-deletion.html
--min-version 1.0.3 texture-copying-feedback-loops.html --min-version 1.0.3 texture-copying-feedback-loops.html
--min-version 1.0.4 texture-corner-case-videos.html --min-version 1.0.4 texture-corner-case-videos.html
--min-version 1.0.4 texture-cube-as-fbo-attachment.html --min-version 1.0.4 texture-cube-as-fbo-attachment.html
--min-version 1.0.3 texture-draw-with-2d-and-cube.html
--min-version 1.0.3 --max-version 1.9.9 texture-fakeblack.html
--min-version 1.0.2 --max-version 1.9.9 texture-formats-test.html
--min-version 1.0.2 texture-hd-dpi.html --min-version 1.0.2 texture-hd-dpi.html
--min-version 1.0.2 --max-version 1.9.9 texture-formats-test.html
texture-mips.html texture-mips.html
--max-version 1.9.9 texture-npot-video.html --max-version 1.9.9 texture-npot-video.html
--max-version 1.9.9 texture-npot.html --max-version 1.9.9 texture-npot.html
@ -49,8 +44,8 @@ texture-size-cube-maps.html
texture-transparent-pixels-initialized.html texture-transparent-pixels-initialized.html
--min-version 1.0.2 texture-upload-cube-maps.html --min-version 1.0.2 texture-upload-cube-maps.html
--min-version 1.0.3 texture-upload-size.html --min-version 1.0.3 texture-upload-size.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-video-transparent.html
--min-version 1.0.4 texture-with-flip-y-and-premultiply-alpha.html --min-version 1.0.4 texture-with-flip-y-and-premultiply-alpha.html
--min-version 1.0.4 upload-from-srcset-with-empty-data.html
--min-version 1.0.4 video-rotation.html
--min-version 1.0.4 png-image-types.html

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

@ -1,5 +1,5 @@
<!-- <!--
Copyright (c) 2020 The Khronos Group Inc. Copyright (c) 2019 The Khronos Group Inc.
Use of this source code is governed by an MIT-style license that can be Use of this source code is governed by an MIT-style license that can be
found in the LICENSE.txt file. found in the LICENSE.txt file.
--> -->
@ -8,7 +8,8 @@ found in the LICENSE.txt file.
<html> <html>
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<link rel="stylesheet" href="../../../resources/js-test-style.css"/> <title>WebGL compressed texture test</title>
<LINK rel="stylesheet" href="../../../resources/js-test-style.css"/>
<script src="../../../js/js-test-pre.js"></script> <script src="../../../js/js-test-pre.js"></script>
<script src="../../../js/webgl-test-utils.js"></script> <script src="../../../js/webgl-test-utils.js"></script>
</head> </head>
@ -16,9 +17,100 @@ found in the LICENSE.txt file.
<div id="description"></div> <div id="description"></div>
<div id="console"></div> <div id="console"></div>
<script> <script>
const contextVersion = 1; "use strict";
description("This test ensures WebGL implementations correctly implement querying for compressed textures when extensions are disabled.");
debug("");
const wtu = WebGLTestUtils;
const gl = wtu.create3DContext();
const COMPRESSED_RGB_PVRTC_4BPPV1_IMG = 0x8C00;
const COMPRESSED_RGBA_PVRTC_4BPPV1_IMG = 0x8C02;
let formats = null;
let ext;
if (!gl) {
testFailed("context does not exist");
} else {
testPassed("context exists");
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))");
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);
});
if (gl.PIXEL_UNPACK_BUFFER) {
const buf = gl.createBuffer();
gl.bindBuffer(gl.PIXEL_UNPACK_BUFFER, buf);
const tex = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, tex);
function validateExt(extName, enumName, blockSize, blockByteSize) {
ext = gl.getExtension(extName);
if (!ext) {
testPassed(`Optional ext ${extName} MAY be unsupported.`);
return;
}
testPassed(`Optional ext ${extName} is supported.`);
gl.bufferData(gl.PIXEL_UNPACK_BUFFER, blockByteSize*2, gl.STATIC_DRAW);
wtu.shouldGenerateGLError(gl, gl.NO_ERROR,
`gl.compressedTexImage2D(gl.TEXTURE_2D, 0, ext.${enumName}, ${blockSize},${blockSize}, 0, ${blockByteSize}, 0)`);
wtu.shouldGenerateGLError(gl, gl.NO_ERROR,
`gl.compressedTexImage2D(gl.TEXTURE_2D, 0, ext.${enumName}, ${blockSize},${blockSize}, 0, ${blockByteSize}, 1)`);
wtu.shouldGenerateGLError(gl, gl.NO_ERROR,
`gl.compressedTexImage2D(gl.TEXTURE_2D, 0, ext.${enumName}, ${blockSize},${blockSize}, 0, ${blockByteSize}, ${blockByteSize})`);
wtu.shouldGenerateGLError(gl, gl.INVALID_OPERATION,
`gl.compressedTexImage2D(gl.TEXTURE_2D, 0, ext.${enumName}, ${blockSize},${blockSize}, 0, ${blockByteSize}, ${blockByteSize+1})`);
wtu.shouldGenerateGLError(gl, gl.NO_ERROR,
`gl.compressedTexSubImage2D(gl.TEXTURE_2D, 0, 0,0, ${blockSize},${blockSize}, ext.${enumName}, ${blockByteSize}, 0)`);
wtu.shouldGenerateGLError(gl, gl.NO_ERROR,
`gl.compressedTexSubImage2D(gl.TEXTURE_2D, 0, 0,0, ${blockSize},${blockSize}, ext.${enumName}, ${blockByteSize}, 1)`);
wtu.shouldGenerateGLError(gl, gl.NO_ERROR,
`gl.compressedTexSubImage2D(gl.TEXTURE_2D, 0, 0,0, ${blockSize},${blockSize}, ext.${enumName}, ${blockByteSize}, ${blockByteSize})`);
wtu.shouldGenerateGLError(gl, gl.INVALID_OPERATION,
`gl.compressedTexSubImage2D(gl.TEXTURE_2D, 0, 0,0, ${blockSize},${blockSize}, ext.${enumName}, ${blockByteSize}, ${blockByteSize+1})`);
}
validateExt('WEBGL_compressed_texture_s3tc', 'COMPRESSED_RGBA_S3TC_DXT5_EXT', 4, 16);
validateExt('WEBGL_compressed_texture_etc1', 'COMPRESSED_RGB_ETC1_WEBGL', 4, 8);
validateExt('WEBGL_compressed_texture_etc', 'COMPRESSED_RGBA8_ETC2_EAC', 4, 16);
validateExt('WEBGL_compressed_texture_astc', 'COMPRESSED_RGBA_ASTC_4x4_KHR', 4, 16);
}
}
var successfullyParsed = true;
</script> </script>
<script src="../../../js/tests/compressed-tex-image.js"></script>
<script src="../../../js/js-test-post.js"></script> <script src="../../../js/js-test-post.js"></script>
</body> </body>
</html> </html>

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

@ -1,167 +0,0 @@
<!--
Copyright (c) 2020 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">
<title>Verifies EXIF orientation is respected when uploading images to WebGL textures</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/tex-image-and-sub-image-utils.js"></script>
</head>
<body onload="run()">
<canvas id="c" width="256" height="256"></canvas>
<div id="description"></div>
<div id="console"></div>
<script>
"use strict";
description();
let wtu = WebGLTestUtils;
let tiu = TexImageUtils;
let canvas = document.getElementById("c");
let gl = wtu.create3DContext(canvas);
let program = tiu.setupTexturedQuad(gl, gl.RGBA);
const resourcePath = "../../../resources/";
const tolerance = 5;
// The locations are written assuming flipY = false. For flipY = true, y = 1.0-y.
const expectedColors = {
top: { location: [ 0.5, 0.25 ], color: [ 255, 0, 0 ] },
left: { location: [ 0.4, 0.5 ], color: [ 0, 0, 255 ] },
right: { location: [ 0.6, 0.5 ], color: [ 255, 255, 0 ] },
bottom: { location: [ 0.5, 0.75 ], color: [ 0, 255, 0 ] },
}
function output(str)
{
debug(str);
bufferedLogToConsole(str);
}
function checkPixels(flipY)
{
for (let place in expectedColors) {
let color = expectedColors[place];
let loc = color.location;
let x = loc[0];
let y = (flipY ? 1.0 - loc[1] : loc[1]);
output(" Checking " + place);
wtu.checkCanvasRect(gl, Math.floor(canvas.width * x), Math.floor(canvas.height * y), 1, 1,
color.color, "shouldBe " + color.color + " +/-" + tolerance, tolerance);
}
}
async function testImageBitmapFromBlobWithFlipY(blob, flipY)
{
let bitmap;
// As a concession to Firefox, which doesn't yet implement
// createImageBitmap with creation options, skip the tests
// involving flipY=true if ImageBitmap creation throws an
// exception, and use the single-argument constructor for the
// flipY=false case.
if (flipY) {
try {
bitmap = await createImageBitmap(blob, {imageOrientation: flipY});
} catch (e) {
output(" (createImageBitmap options not supported - skipping flipY=true case)");
return;
}
} else {
bitmap = await createImageBitmap(blob);
}
output(" Testing texImage2D, flipY = " + flipY);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, bitmap);
wtu.clearAndDrawUnitQuad(gl, [0, 0, 0, 255]);
checkPixels(flipY);
output(" Testing texSubImage2D, flipY = " + flipY);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, bitmap.width, bitmap.height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE, bitmap);
wtu.clearAndDrawUnitQuad(gl, [0, 0, 0, 255]);
checkPixels(flipY);
}
async function testImageBitmapFromBlob(filename)
{
let response = await fetch(resourcePath + filename);
let blob = await response.blob();
output("----------------------------------------------------------------");
output("Testing " + filename + " via ImageBitmap from Blob");
await testImageBitmapFromBlobWithFlipY(blob, true);
await testImageBitmapFromBlobWithFlipY(blob, false);
}
async function testImageElementWithFlipY(image, flipY)
{
output(" Testing texImage2D, flipY = " + flipY);
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, flipY);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image);
wtu.clearAndDrawUnitQuad(gl, [0, 0, 0, 255]);
checkPixels(flipY);
output(" Testing texSubImage2D, flipY = " + flipY);
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, flipY);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, image.width, image.height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE, image);
wtu.clearAndDrawUnitQuad(gl, [0, 0, 0, 255]);
checkPixels(flipY);
}
async function testImageElement(filename)
{
let image = new Image();
image.src = resourcePath + filename;
await image.decode();
output("----------------------------------------------------------------");
output("Testing " + filename + " via HTMLImageElement");
await testImageElementWithFlipY(image, true);
await testImageElementWithFlipY(image, false);
}
async function testSingleImage(filename)
{
await testImageBitmapFromBlob(filename);
await testImageElement(filename);
}
async function run()
{
let tex = gl.createTexture();
// Bind the texture to the default texture unit 0
gl.bindTexture(gl.TEXTURE_2D, tex);
// Set up texture parameters
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
const filenames = [
"exif-orientation-test-1-normal.jpg",
"exif-orientation-test-2-mirror-horizontal.jpg",
"exif-orientation-test-3-rotate-180.jpg",
"exif-orientation-test-4-mirror-vertical.jpg",
"exif-orientation-test-5-mirror-horizontal-90-ccw.jpg",
"exif-orientation-test-6-90-ccw.jpg",
"exif-orientation-test-7-mirror-horizontal-90-cw.jpg",
"exif-orientation-test-8-90-cw.jpg",
];
for (let fn of filenames) {
await testSingleImage(fn);
}
finishTest();
}
var successfullyParsed = true;
</script>
</body>
</html>

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

@ -12,12 +12,6 @@ found in the LICENSE.txt file.
<link rel="stylesheet" href="../../../resources/js-test-style.css"/> <link rel="stylesheet" href="../../../resources/js-test-style.css"/>
<script src="../../../js/js-test-pre.js"></script> <script src="../../../js/js-test-pre.js"></script>
<script src="../../../js/webgl-test-utils.js"></script> <script src="../../../js/webgl-test-utils.js"></script>
</head>
<body>
<div id="description"></div>
<div id="console"></div>
<canvas id="canvas"></canvas>
<img id="img" style="display:none;">
<script> <script>
"use strict"; "use strict";
var wtu = WebGLTestUtils; var wtu = WebGLTestUtils;
@ -39,7 +33,7 @@ var localImgUrl = "../../../resources/opengl_logo.jpg";
var imgDomain; var imgDomain;
var pageDomain; var pageDomain;
function imageLoaded(img) { function imageLoaded() {
description("This test ensures WebGL implementations for OffscreenCanvas follow proper same-origin restrictions."); description("This test ensures WebGL implementations for OffscreenCanvas follow proper same-origin restrictions.");
if (!window.OffscreenCanvas) { if (!window.OffscreenCanvas) {
@ -48,6 +42,8 @@ function imageLoaded(img) {
return; return;
} }
var img = this;
assertMsg(img.width > 0 && img.height > 0, "img was loaded"); assertMsg(img.width > 0 && img.height > 0, "img was loaded");
imgDomain = wtu.getBaseDomain(wtu.getHost(img.src)); imgDomain = wtu.getBaseDomain(wtu.getHost(img.src));
pageDomain = wtu.getBaseDomain(window.location.host); pageDomain = wtu.getBaseDomain(window.location.host);
@ -109,17 +105,13 @@ function imageLoaded(img) {
finishTest(); finishTest();
} }
(async function() { wtu.setupImageForCrossOriginTest("#img", defaultImgUrl, localImgUrl, imageLoaded);
const img = document.getElementById('img');
try {
await wtu.awaitOrTimeout(wtu.loadCrossOriginImage(img, defaultImgUrl, localImgUrl));
} catch (e) {
testFailed(`Image setup failed (${e}).`);
finishTest();
return;
}
imageLoaded(img);
})();
</script> </script>
</head>
<body>
<div id="description"></div>
<div id="console"></div>
<canvas id="canvas"></canvas>
<img id="img" style="display:none;">
</body> </body>
</html> </html>

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

@ -12,13 +12,6 @@ found in the LICENSE.txt file.
<link rel="stylesheet" href="../../../resources/js-test-style.css"/> <link rel="stylesheet" href="../../../resources/js-test-style.css"/>
<script src="../../../js/js-test-pre.js"></script> <script src="../../../js/js-test-pre.js"></script>
<script src="../../../js/webgl-test-utils.js"></script> <script src="../../../js/webgl-test-utils.js"></script>
</head>
<body>
<div id="description"></div>
<div id="console"></div>
<canvas id="canvas1"></canvas>
<canvas id="canvas2"></canvas>
<img id="img" style="display:none;">
<script> <script>
"use strict"; "use strict";
var wtu = WebGLTestUtils; var wtu = WebGLTestUtils;
@ -41,8 +34,9 @@ var imgDomain;
var pageDomain; var pageDomain;
var successfullyParsed; var successfullyParsed;
function imageLoaded(img) { function imageLoaded() {
description("This test ensures WebGL implementations follow proper same-origin restrictions."); description("This test ensures WebGL implementations follow proper same-origin restrictions.");
var img = this;
assertMsg(img.width > 0 && img.height > 0, "img was loaded"); assertMsg(img.width > 0 && img.height > 0, "img was loaded");
imgDomain = wtu.getBaseDomain(wtu.getHost(img.src)); imgDomain = wtu.getBaseDomain(wtu.getHost(img.src));
@ -121,17 +115,14 @@ function imageLoaded(img) {
notifyFinishedToHarness(); notifyFinishedToHarness();
} }
(async function() { wtu.setupImageForCrossOriginTest("#img", defaultImgUrl, localImgUrl, imageLoaded);
const img = document.getElementById('img');
try {
await wtu.awaitOrTimeout(wtu.loadCrossOriginImage(img, defaultImgUrl, localImgUrl));
} catch (e) {
testFailed(`Image setup failed (${e}).`);
finishTest();
return;
}
imageLoaded(img);
})();
</script> </script>
</head>
<body>
<div id="description"></div>
<div id="console"></div>
<canvas id="canvas1"></canvas>
<canvas id="canvas2"></canvas>
<img id="img" style="display:none;">
</body> </body>
</html> </html>

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

@ -1,164 +0,0 @@
<!--
Copyright (c) 2021 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>
</head>
<body>
<div id="description"></div>
<div id="console"></div>
<script>
"use strict";
description("This test verifies correct channel mapping of different PNG image types.");
const testData = {
"Grayscale": {
src: [
// [0x40]
"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAAAAAA6fptVAAAACklEQVQI12NwAAAAQgBBg7nsrQAAAABJRU5ErkJggg==",
// [0x4040]
"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABEAAAAABq7kcWAAAAC0lEQVQI12NwcAAAAMMAgUenLEIAAAAASUVORK5CYII="
],
expectations: [
{ color: [0x00, 0x00, 0x00, 0xFF], format: "ALPHA" },
{ color: [0x40, 0x40, 0x40, 0xFF], format: "RGB" },
{ color: [0x40, 0x40, 0x40, 0xFF], format: "RGBA" },
{ color: [0x40, 0x40, 0x40, 0xFF], format: "LUMINANCE" },
{ color: [0x40, 0x40, 0x40, 0xFF], format: "LUMINANCE_ALPHA" },
{ color: [0x40, 0x00, 0x00, 0xFF], format: "RED", internalformat: "R8" },
{ color: [0x40, 0x40, 0x00, 0xFF], format: "RG", internalformat: "RG8" }
]
},
"Grayscale Alpha": {
src: [
// [0x40, 0x80]
"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVQI12NwaAAAAQMAwUxZTl4AAAAASUVORK5CYII=",
// [0x4040, 0x8080]
"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABEAQAAADljNBBAAAADUlEQVQI12NwcGhoAAADRQGBoxssPgAAAABJRU5ErkJggg=="
],
expectations: [
{ color: [0x00, 0x00, 0x00, 0x80], format: "ALPHA" },
{ color: [0x40, 0x40, 0x40, 0xFF], format: "RGB" },
{ color: [0x40, 0x40, 0x40, 0x80], format: "RGBA" },
{ color: [0x40, 0x40, 0x40, 0xFF], format: "LUMINANCE" },
{ color: [0x40, 0x40, 0x40, 0x80], format: "LUMINANCE_ALPHA" },
{ color: [0x40, 0x00, 0x00, 0xFF], format: "RED", internalformat: "R8" },
{ color: [0x40, 0x40, 0x00, 0xFF], format: "RG", internalformat: "RG8" }
]
},
"Color": {
src: [
// [0xBF, 0x7F, 0xFF]
"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAADElEQVQI12PYX/8fAAQ+Aj5BqwprAAAAAElFTkSuQmCC",
// [0xBFBF, 0x7F7F, 0xFFFF]
"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABEAIAAADA54+dAAAAD0lEQVQI12PYv7++/v9/AA6yBHvtbgBNAAAAAElFTkSuQmCC"
],
expectations: [
{ color: [0x00, 0x00, 0x00, 0xFF], format: "ALPHA" },
{ color: [0xBF, 0x7F, 0xFF, 0xFF], format: "RGB" },
{ color: [0xBF, 0x7F, 0xFF, 0xFF], format: "RGBA" },
{ color: [0xBF, 0xBF, 0xBF, 0xFF], format: "LUMINANCE" },
{ color: [0xBF, 0xBF, 0xBF, 0xFF], format: "LUMINANCE_ALPHA" },
{ color: [0xBF, 0x00, 0x00, 0xFF], format: "RED", internalformat: "R8" },
{ color: [0xBF, 0x7F, 0x00, 0xFF], format: "RG", internalformat: "RG8" }
]
},
"Color Alpha": {
src: [
// [0xBF, 0x7F, 0xFF, 0x40]
"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVQI12PYX//fAQAGvAJ+xPMwKQAAAABJRU5ErkJggg==",
// [0xBFBF, 0x7F7F, 0xFFFF, 0x4040]
"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABEAYAAABPhRjKAAAAEUlEQVQI12PYv7++/v9/BwcAGGgE+8YN4XUAAAAASUVORK5CYII="
],
expectations: [
{ color: [0x00, 0x00, 0x00, 0x40], format: "ALPHA" },
{ color: [0xBF, 0x7F, 0xFF, 0xFF], format: "RGB" },
{ color: [0xBF, 0x7F, 0xFF, 0x40], format: "RGBA" },
{ color: [0xBF, 0xBF, 0xBF, 0xFF], format: "LUMINANCE" },
{ color: [0xBF, 0xBF, 0xBF, 0x40], format: "LUMINANCE_ALPHA" },
{ color: [0xBF, 0x00, 0x00, 0xFF], format: "RED", internalformat: "R8" },
{ color: [0xBF, 0x7F, 0x00, 0xFF], format: "RG", internalformat: "RG8" }
]
}
};
const wtu = WebGLTestUtils;
const gl = wtu.create3DContext();
wtu.setupTexturedQuad(gl);
gl.bindTexture(gl.TEXTURE_2D, gl.createTexture());
(async () => {
for (const [type, testCase] of Object.entries(testData)) {
if (testCase.src.length != 2) throw new Error('testCase.src.length != 2');
let images = testCase.src.map(src => loadImage(src));
images = await Promise.all(images);
debug("");
debug("");
debug(`PNG image type ${type} with RGBA values of ${testCase.expectations[2].color}`);
let formats = testCase.expectations;
if (!wtu.isWebGL2(gl)) {
formats = formats.filter((f) => !f.internalformat);
}
for (const f of formats) {
debug("");
debug(`GL format: ${f.format}`);
function check(data, description) {
debug(`Upload ${description}`);
gl.texImage2D(
gl.TEXTURE_2D,
0,
gl[f.internalformat || f.format],
gl[f.format],
gl.UNSIGNED_BYTE,
data
);
wtu.glErrorShouldBe(gl, gl.NO_ERROR);
wtu.clearAndDrawUnitQuad(gl);
wtu.checkCanvas(gl, f.color, undefined, 1);
}
check(images[0].image, "8-bit PNG from Image");
check(images[1].image, "16-bit PNG from Image");
if (images[0].bitmap) {
check(images[0].bitmap, "8-bit PNG from ImageBitmap");
check(images[1].bitmap, "16-bit PNG from ImageBitmap");
}
}
}
finishTest();
})();
async function loadImage(src) {
const img = new Image();
img.src = src;
await img.decode();
const ret = { image: img };
if (self.createImageBitmap) {
try {
ret.bitmap = await createImageBitmap(img, {
premultiplyAlpha: "none",
});
} catch {}
}
return ret;
}
var successfullyParsed = true;
</script>
</body>
</html>

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

@ -264,6 +264,7 @@ function runTest(bindingTarget, program)
} }
} }
} }
} }
var gl = wtu.create3DContext("example"); var gl = wtu.create3DContext("example");
@ -274,29 +275,6 @@ program = wtu.setupTexturedQuadWithCubeMap(gl);
runTest(gl.TEXTURE_CUBE_MAP, program); runTest(gl.TEXTURE_CUBE_MAP, program);
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no errors"); wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no errors");
const tex = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, tex);
const validDatas = [
`new Uint8Array(4)`,
`new Uint8Array(new ArrayBuffer(4))`,
`new Uint8ClampedArray(4)`,
`new Uint8ClampedArray(new ArrayBuffer(4))`,
];
if (window.SharedArrayBuffer) {
validDatas.push(
`new Uint8Array(new SharedArrayBuffer(4))`,
`new Uint8ClampedArray(new SharedArrayBuffer(4))`
);
}
for (const x of validDatas) {
shouldNotThrow(`gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1,1, 0, gl.RGBA, gl.UNSIGNED_BYTE, ${x});`);
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no errors");
shouldNotThrow(`gl.texSubImage2D(gl.TEXTURE_2D, 0, 0,0, 1,1, gl.RGBA, gl.UNSIGNED_BYTE, ${x});`);
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be no errors");
}
var successfullyParsed = true; var successfullyParsed = true;
</script> </script>
<script src="../../../js/js-test-post.js"></script> <script src="../../../js/js-test-post.js"></script>

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

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

@ -1,91 +0,0 @@
<!--
Copyright (c) 2020 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">
<title>WebGL Texture Copying and Deletion 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="1" height="1" style="width: 40px; height: 40px;"></canvas>
<div id="description"></div>
<div id="console"></div>
<script>
"use strict";
description('Checks that texture copying and deletion work correctly together.');
debug('Regression test for <a href="http://anglebug.com/4267">http://anglebug.com/4267</a>');
const wtu = WebGLTestUtils;
const canvas = document.getElementById("example");
canvas.addEventListener('webglcontextlost', contextLost, false);
let contextWasLost = false;
function contextLost(e) {
e.preventDefault();
contextWasLost = true;
debug("***context lost -- should not happen***");
}
const gl = wtu.create3DContext(canvas);
const texture = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, texture);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 2, 2, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
const texture2 = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, texture2);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 2, 2, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
const framebuffer = gl.createFramebuffer();
gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer);
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0);
assertMsg(gl.checkFramebufferStatus(gl.FRAMEBUFFER) == gl.FRAMEBUFFER_COMPLETE,
"framebuffer should be FRAMEBUFFER_COMPLETE.");
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "after setup");
// This test does not call getError, because doing so seems to cause
// an implicit flush which intermittently masks the bug.
debug("");
debug("testing copyTexImage2D");
gl.bindTexture(gl.TEXTURE_2D, texture);
gl.copyTexImage2D(gl.TEXTURE_2D, 1, gl.RGBA, 0, 0, 2, 2, 0);
// Not necessary to do any CopyTexImage2D operations to texture2.
debug("");
debug("testing copyTexSubImage2D");
gl.bindTexture(gl.TEXTURE_2D, texture);
gl.copyTexSubImage2D(gl.TEXTURE_2D, 1, 0, 0, 0, 0, 1, 1);
gl.bindTexture(gl.TEXTURE_2D, texture2);
gl.copyTexSubImage2D(gl.TEXTURE_2D, 0, 0, 0, 0, 0, 1, 1);
debug('deleting framebuffer');
gl.deleteFramebuffer(framebuffer);
debug('deleting texture');
gl.deleteTexture(texture);
debug('deleting texture2');
// On buggy driver, crashes during this deleteTexture call.
gl.deleteTexture(texture2);
setTimeout(function() {
shouldBe("contextWasLost", "false");
finishTest();
}, 1000);
</script>
</body>
</html>

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

@ -99,33 +99,31 @@ function runOneIteration(videoElement, useTexSubImage2D)
// - Left is green and right is transparent-blended-with-red // - Left is green and right is transparent-blended-with-red
let leftIsGreen = false, leftIsRed = false, rightIsBlue = false, rightIsRed = false; let leftIsGreen = false, leftIsRed = false, rightIsBlue = false, rightIsRed = false;
let greenRedError = "", redBlueError = ""; let greenRedError = "", redBlueError = "";
let leftGreenError = "", rightBlueError = "";
let bufLeft, bufRight;
wtu.checkCanvasRectColor(gl, 4, 4, 8, 24, green, tolerance, wtu.checkCanvasRectColor(gl, 4, 4, 8, 24, green, tolerance,
/* sameFn */ () => { leftIsGreen = true; }, /* differentFn */ (m, b) => { leftGreenError = m; bufLeft = b;}, debug); /* sameFn */ () => { leftIsGreen = true; }, /* differentFn */ m => {}, debug);
wtu.checkCanvasRectColor(gl, 20, 4, 8, 24, red, tolerance, wtu.checkCanvasRectColor(gl, 20, 4, 8, 24, red, tolerance,
/* sameFn */ () => { rightIsRed = true; }, /* differentFn */ (m, b) => { greenRedError = m; bufRight = b;}, debug); /* sameFn */ () => { rightIsRed = true; }, /* differentFn */ m => { greenRedError = m; }, debug);
// - Right is blue and left is transparent-blended-with-red // - Right is blue and left is transparent-blended-with-red
wtu.checkCanvasRectColor(gl, 20, 4, 8, 24, blue, tolerance, wtu.checkCanvasRectColor(gl, 20, 4, 8, 24, blue, tolerance,
/* sameFn */ () => { rightIsBlue = true; }, /* differentFn */ (m, b) => { rightBlueError = m; bufRight = b;}, debug); /* sameFn */ () => { rightIsBlue = true; }, /* differentFn */ m => {}, debug);
wtu.checkCanvasRectColor(gl, 4, 4, 8, 24, red, tolerance, wtu.checkCanvasRectColor(gl, 4, 4, 8, 24, red, tolerance,
/* sameFn */ () => { leftIsRed = true; }, /* differentFn */ (m, b) => { redBlueError = m; bufLeft = b;}, debug); /* sameFn */ () => { leftIsRed = true; }, /* differentFn */ m => { redBlueError = m; }, debug);
if (leftIsGreen) { if (leftIsGreen) {
if (rightIsRed) { if (rightIsRed) {
testPassed("left is green, right is transparent-blended-with-red"); testPassed("left is green, right is transparent-blended-with-red")
} else { } else {
testFailed("left is green, but: " + greenRedError + "\n" + bufRight); testFailed("left is green, but: " + greenRedError);
} }
} else if (rightIsBlue) { } else if (rightIsBlue) {
if (leftIsRed) { if (leftIsRed) {
testPassed("right is blue, left is transparent-blended-with-red"); testPassed("right is blue, left is transparent-blended-with-red");
} else { } else {
testFailed("right is blue, but: " + redBlueError + "\n" + bufLeft); testFailed("right is blue, but: " + redBlueError);
} }
} else { } else {
testFailed("neither left is green nor right is blue \n" + leftGreenError + "\n" + rightBlueError + "\n" + bufLeft + "\n" + bufRight); testFailed("neither left is green nor right is blue")
} }
} }
</script> </script>

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

@ -1,44 +0,0 @@
<!--
Copyright (c) 2020 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"/>
<title>Upload From Srcset With Empty Data</title>
<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>
<img srcset="data:,a 1x, data:,b 1w" id="i">
<script>
"use strict";
var wtu = WebGLTestUtils;
var successfullyParsed;
description("This test ensures WebGL implementations handle srcsets with empty data.");
debug("Regression test for <a href='http://crbug.com/1085044'>http://crbug.com/1085044</a>");
let gl = wtu.create3DContext();
// Note we run this test synchronously, rather than running it in an async
// function called after "wtu.awaitOrTimeout(img.decode());". This reproduces
// the bug more reliably.
let img = document.getElementById("i");
let tex = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, tex);
// Implementations can decide how to respond to these kinds of bad
// inputs, as long as they don't crash.
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, img);
finishTest();
</script>
</body>
</html>

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

@ -1,167 +0,0 @@
<!--
Copyright (c) 2021 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">
<title>Verifies rotation metadata tag is respected when uploading videos to WebGL textures.</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/tex-image-and-sub-image-utils.js"></script>
</head>
<body onload="run()">
<canvas id="c" width="256" height="256"></canvas>
<div id="description"></div>
<div id="console"></div>
<script>
"use strict";
description();
let wtu = WebGLTestUtils;
let tiu = TexImageUtils;
let canvas = document.getElementById("c");
let gl = wtu.create3DContext(canvas);
let program = tiu.setupTexturedQuad(gl, gl.RGBA);
const resourcePath = "../../../resources/";
const mp4Tolerance = 10;
// Significantly higher tolerance needed for VP9 tests. http://crbug.com/1219015 .
const vp9Tolerance = 45;
const expectedColors = {
top: { location: [0.5, 0.25], color: [255, 0, 0] },
left: { location: [0.4, 0.5], color: [0, 0, 255] },
right: { location: [0.6, 0.5], color: [255, 255, 0] },
bottom: { location: [0.5, 0.75], color: [0, 255, 0] },
}
function output(str) {
debug(str);
bufferedLogToConsole(str);
}
function checkPixels(tolerance) {
for (let place in expectedColors) {
let color = expectedColors[place];
let loc = color.location;
let x = loc[0];
let y = loc[1];
output(" Checking " + place);
wtu.checkCanvasRect(gl, Math.floor(canvas.width * x), Math.floor(canvas.height * y), 1, 1,
color.color, "shouldBe " + color.color + " +/-" + tolerance, tolerance);
}
}
function loadVideoElement(filename) {
return new Promise((resolve) => {
const video = document.createElement('video');
video.crossOrigin = 'anonymous';
video.src = resourcePath + filename;
wtu.startPlayingAndWaitForVideo(video, resolve);
});
}
async function testVideoElement(filename, isVP9) {
const video = await loadVideoElement(filename);
output("----------------------------------------------------------------");
output("Testing " + filename + " via HTMLVideoElement");
output(" Testing texImage2D");
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, video);
wtu.clearAndDrawUnitQuad(gl, [0, 0, 0, 255]);
const localTolerance = isVP9 ? vp9Tolerance : mp4Tolerance;
checkPixels(localTolerance);
output(" Testing texSubImage2D");
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, video.videoWidth, video.videoHeight, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE, video);
wtu.clearAndDrawUnitQuad(gl, [0, 0, 0, 255]);
checkPixels(localTolerance);
}
async function run() {
await (async () => {
const video = document.createElement('video');
if (!video.canPlayType) {
testFailed("video.canPlayType required method missing");
return;
}
let supports_h264 = !!video.canPlayType('video/mp4; codecs="avc1.42E01E"').replace(/no/, '');
let supports_vp9 = !!video.canPlayType('video/mp4; codecs="vp09.00.10.08"').replace(/no/, '');
if (!supports_h264 && !supports_vp9) {
testFailed("No supported video types.");
return;
}
let tex = gl.createTexture();
// Bind the texture to the default texture unit 0
gl.bindTexture(gl.TEXTURE_2D, tex);
// Set up texture parameters
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
// These files were created by converting exif-orientation-test.psd to mp4
// files, rotating them using the transpose filter, and adding rotate metadata, all
// using the ffmpeg command-line tool.
//
// From sdk/tests/resources/ directory:
//
// 0:
// ffmpeg -noautorotate -i exif-orientation-originals\exif-orientation-test.psd -vf scale=128x96 -pix_fmt yuv420p -y temp.mp4
// ffmpeg -i temp.mp4 -c copy -metadata:s:v:0 rotate=0 video-rotation-0.mp4
// ffmpeg -noautorotate -i exif-orientation-originals\exif-orientation-test.psd -vf scale=128x96 -pix_fmt yuv420p -crf 0 -vcodec libvpx-vp9 -y temp.mp4
// ffmpeg -i temp.mp4 -c copy -metadata:s:v:0 rotate=0 video-rotation-0.vp9.mp4
//
// 90:
// ffmpeg -noautorotate -i exif-orientation-originals\exif-orientation-test.psd -vf scale=128x96,transpose=2 -pix_fmt yuv420p -y temp.mp4
// ffmpeg -i temp.mp4 -c copy -metadata:s:v:0 rotate=270 video-rotation-90.mp4
// ffmpeg -noautorotate -i exif-orientation-originals\exif-orientation-test.psd -vf scale=128x96,transpose=2 -pix_fmt yuv420p -crf 0 -vcodec libvpx-vp9 -y temp.mp4
// ffmpeg -i temp.mp4 -c copy -metadata:s:v:0 rotate=270 video-rotation-90.vp9.mp4
//
// 180:
// ffmpeg -noautorotate -i exif-orientation-originals\exif-orientation-test.psd -vf scale=128x96,transpose=2,transpose=2 -pix_fmt yuv420p -y temp.mp4
// ffmpeg -i temp.mp4 -c copy -metadata:s:v:0 rotate=180 video-rotation-180.mp4
// ffmpeg -noautorotate -i exif-orientation-originals\exif-orientation-test.psd -vf scale=128x96,transpose=2,transpose=2 -pix_fmt yuv420p -crf 0 -vcodec libvpx-vp9 -y temp.mp4
// ffmpeg -i temp.mp4 -c copy -metadata:s:v:0 rotate=180 video-rotation-180.vp9.mp4
//
// 270:
// ffmpeg -noautorotate -i exif-orientation-originals\exif-orientation-test.psd -vf scale=128x96,transpose=1 -pix_fmt yuv420p -y temp.mp4
// ffmpeg -i temp.mp4 -c copy -metadata:s:v:0 rotate=90 video-rotation-270.mp4
// ffmpeg -noautorotate -i exif-orientation-originals\exif-orientation-test.psd -vf scale=128x96,transpose=1 -pix_fmt yuv420p -crf 0 -vcodec libvpx-vp9 -y temp.mp4
// ffmpeg -i temp.mp4 -c copy -metadata:s:v:0 rotate=90 video-rotation-270.vp9.mp4
const filenames = [
"video-rotation-0",
"video-rotation-90",
"video-rotation-180",
"video-rotation-270",
];
if (supports_h264) {
for (let fn of filenames)
await testVideoElement(fn + ".mp4", false);
}
if (supports_vp9) {
for (let fn of filenames)
await testVideoElement(fn + ".vp9.mp4", true);
}
})();
finishTest();
}
var successfullyParsed = true;
</script>
</body>
</html>

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

@ -164,9 +164,9 @@ function testInheritanceHierarchy() {
try { try {
var foo = ArrayBufferView; var foo = ArrayBufferView;
testFailed('ArrayBufferView is a typedef and should not be defined'); testFailed('ArrayBufferView has [NoInterfaceObject] extended attribute and should not be defined');
} catch (e) { } catch (e) {
testPassed('ArrayBufferView is a typedef and was (correctly) not defined'); testPassed('ArrayBufferView has [NoInterfaceObject] extended attribute and was (correctly) not defined');
} }
// Uint8ClampedArray inherited from Uint8Array in earlier versions // Uint8ClampedArray inherited from Uint8Array in earlier versions

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

@ -33,25 +33,6 @@ found in the LICENSE.txt file.
gl_FragColor = vec4(color[0]$(elem), color[1]$(elem), color[2]$(elem), 1); gl_FragColor = vec4(color[0]$(elem), color[1]$(elem), color[2]$(elem), 1);
} }
</script> </script>
<script id="vshader300" type="x-shader/x-vertex">
#version 300 es
in vec4 a_position;
void main()
{
gl_Position = a_position;
}
</script>
<script id="fshader300" type="x-shader/x-fragment">
#version 300 es
precision mediump float;
uniform $(type) color[3];
out vec4 o_FragColor;
void main()
{
o_FragColor = vec4(color[0]$(elem), color[1]$(elem), color[2]$(elem), 1);
}
</script>
<script> <script>
"use strict"; "use strict";
description(); description();
@ -61,17 +42,10 @@ var MaxInt32PlusOne = 4294967296;
var wtu = WebGLTestUtils; var wtu = WebGLTestUtils;
var gl = wtu.create3DContext("example"); var gl = wtu.create3DContext("example");
const contextVersion = wtu.getDefault3DContextVersion(); var vSrc = wtu.getScript("vshader");
var fTemplate = wtu.getScript("fshader");
let [vElemId, fElemId] = ["vshader", "fshader"]; var typeInfos = [
if (contextVersion >= 2) {
[vElemId, fElemId] = ["vshader300", "fshader300"];
}
var vSrc = wtu.getScript(vElemId).trim();
var fTemplate = wtu.getScript(fElemId).trim();
const typeInfos = [
{ type: 'float', { type: 'float',
jsTypeOf: 'number', jsTypeOf: 'number',
setter: 'uniform1fv', setter: 'uniform1fv',
@ -211,428 +185,6 @@ const typeInfos = [
} }
]; ];
if (contextVersion >= 2) {
const more = [
{ type: 'int',
jsTypeOf: 'number',
setter: 'uniform1iv',
elem: '',
numSrcValues: 3,
invalidSet: function(loc) {
gl.uniform2iv(loc, [1, 2]);
},
srcValueAsString: function(index, srcValues) {
return srcValues[index].toString();
},
returnValueAsString: function(value) {
return value === null ? 'null' : value.toString();
},
checkType: function(value) {
return typeof value === 'number';
},
checkValue: function(typeInfo, index, value) {
return typeInfo.srcValues[index] == value;
},
srcValues: [16, 15, 14],
srcValuesLess: [],
srcValuesLessMultiple: [16],
srcValuesMoreMultiple: [16, 15, 14, 13],
srcValuesNonMultiple: null,
},
{ type: 'ivec2',
jsTypeOf: 'Int32Array',
setter: 'uniform2iv',
elem: '[1]',
numSrcValues: 3,
invalidSet: function(loc) {
gl.uniform1iv(loc, [2]);
},
illegalSet: function(loc) {
gl.uniform1iv(loc, 2);
},
srcValueAsString: function(index, srcValues) {
return "[" + srcValues[index * 2 + 0].toString() + ", " +
srcValues[index * 2 + 1].toString() + "]";
},
returnValueAsString: function(value) {
return value === null ? 'null' : ("[" + value[0] + ", " + value[1] + "]");
},
checkType: function(value) {
return value &&
typeof value.length === 'number' &&
value.length == 2;
},
checkValue: function(typeInfo, index, value) {
return value !== null &&
typeInfo.srcValues[index * 2 + 0] == value[0] &&
typeInfo.srcValues[index * 2 + 1] == value[1];
},
srcValues: [16, 15, 14, 13, 12, 11],
srcValuesLess: [16],
srcValuesLessMultiple: [16, 15, 14, 13],
srcValuesMoreMultiple: [16, 15, 14, 13, 12, 11, 10, 9],
srcValuesNonMultiple: [16, 15, 14, 13, 12, 11, 10],
},
{ type: 'ivec3',
jsTypeOf: 'Int32Array',
setter: 'uniform3iv',
elem: '[2]',
numSrcValues: 3,
invalidSet: function(loc) {
gl.uniform1iv(loc, [2]);
},
illegalSet: function(loc) {
gl.uniform1iv(loc, 2);
},
srcValueAsString: function(index, srcValues) {
return "[" + srcValues[index * 3 + 0].toString() + ", " +
srcValues[index * 3 + 1].toString() + ", " +
srcValues[index * 3 + 2].toString() + "]";
},
returnValueAsString: function(value) {
return value === null ? 'null' :
("[" + value[0] + ", " + value[1] + ", " + value[2] + "]");
},
checkType: function(value) {
return value &&
typeof value.length === 'number' &&
value.length == 3;
},
checkValue: function(typeInfo, index, value) {
return value !== null &&
typeInfo.srcValues[index * 3 + 0] == value[0] &&
typeInfo.srcValues[index * 3 + 1] == value[1] &&
typeInfo.srcValues[index * 3 + 2] == value[2];
},
srcValues: [16, 15, 14, 13, 12, 11, 10, 9, 8],
srcValuesLess: [16, 15],
srcValuesLessMultiple: [16, 15, 14, 13, 12, 11],
srcValuesMoreMultiple: [16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2],
srcValuesNonMultiple: [16, 15, 14, 13, 12, 11, 10, 9, 8, 7],
},
{ type: 'ivec4',
jsTypeOf: 'Int32Array',
setter: 'uniform4iv',
elem: '[3]',
numSrcValues: 3,
invalidSet: function(loc) {
gl.uniform1iv(loc, [2]);
},
illegalSet: function(loc) {
gl.uniform1iv(loc, 2);
},
srcValueAsString: function(index, srcValues) {
return "[" + srcValues[index * 4 + 0].toString() + ", " +
srcValues[index * 4 + 1].toString() + ", " +
srcValues[index * 4 + 2].toString() + ", " +
srcValues[index * 4 + 3].toString() + "]";
},
returnValueAsString: function(value) {
return value === null ? 'null' :
("[" + value[0] + ", " + value[1] +
", " + value[2] + ", " + value[3] + "]");
},
checkType: function(value) {
return value &&
typeof value.length === 'number' &&
value.length == 4;
},
checkValue: function(typeInfo, index, value) {
return value !== null &&
typeInfo.srcValues[index * 4 + 0] == value[0] &&
typeInfo.srcValues[index * 4 + 1] == value[1] &&
typeInfo.srcValues[index * 4 + 2] == value[2] &&
typeInfo.srcValues[index * 4 + 3] == value[3];
},
srcValues: [16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5],
srcValuesLess: [16, 15, 14],
srcValuesLessMultiple: [16, 15, 14, 13, 12, 11, 10, 9],
srcValuesMoreMultiple: [16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1],
srcValuesNonMultiple: [16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4],
},
{ type: 'uint',
jsTypeOf: 'number',
setter: 'uniform1uiv',
elem: '',
numSrcValues: 3,
invalidSet: function(loc) {
gl.uniform2uiv(loc, [1, 2]);
},
srcValueAsString: function(index, srcValues) {
return srcValues[index].toString();
},
returnValueAsString: function(value) {
return value === null ? 'null' : value.toString();
},
checkType: function(value) {
return typeof value === 'number';
},
checkValue: function(typeInfo, index, value) {
return typeInfo.srcValues[index] == value;
},
srcValues: [16, 15, 14],
srcValuesLess: [],
srcValuesLessMultiple: [16],
srcValuesMoreMultiple: [16, 15, 14, 13],
srcValuesNonMultiple: null,
},
{ type: 'uvec2',
jsTypeOf: 'Uint32Array',
setter: 'uniform2uiv',
elem: '[1]',
numSrcValues: 3,
invalidSet: function(loc) {
gl.uniform1uiv(loc, [2]);
},
illegalSet: function(loc) {
gl.uniform1uiv(loc, 2);
},
srcValueAsString: function(index, srcValues) {
return "[" + srcValues[index * 2 + 0].toString() + ", " +
srcValues[index * 2 + 1].toString() + "]";
},
returnValueAsString: function(value) {
return value === null ? 'null' : ("[" + value[0] + ", " + value[1] + "]");
},
checkType: function(value) {
return value &&
typeof value.length === 'number' &&
value.length == 2;
},
checkValue: function(typeInfo, index, value) {
return value !== null &&
typeInfo.srcValues[index * 2 + 0] == value[0] &&
typeInfo.srcValues[index * 2 + 1] == value[1];
},
srcValues: [16, 15, 14, 13, 12, 11],
srcValuesLess: [16],
srcValuesLessMultiple: [16, 15, 14, 13],
srcValuesMoreMultiple: [16, 15, 14, 13, 12, 11, 10, 9],
srcValuesNonMultiple: [16, 15, 14, 13, 12, 11, 10],
},
{ type: 'uvec3',
jsTypeOf: 'Uint32Array',
setter: 'uniform3uiv',
elem: '[2]',
numSrcValues: 3,
invalidSet: function(loc) {
gl.uniform1uiv(loc, [2]);
},
illegalSet: function(loc) {
gl.uniform1uiv(loc, 2);
},
srcValueAsString: function(index, srcValues) {
return "[" + srcValues[index * 3 + 0].toString() + ", " +
srcValues[index * 3 + 1].toString() + ", " +
srcValues[index * 3 + 2].toString() + "]";
},
returnValueAsString: function(value) {
return value === null ? 'null' :
("[" + value[0] + ", " + value[1] + ", " + value[2] + "]");
},
checkType: function(value) {
return value &&
typeof value.length === 'number' &&
value.length == 3;
},
checkValue: function(typeInfo, index, value) {
return value !== null &&
typeInfo.srcValues[index * 3 + 0] == value[0] &&
typeInfo.srcValues[index * 3 + 1] == value[1] &&
typeInfo.srcValues[index * 3 + 2] == value[2];
},
srcValues: [16, 15, 14, 13, 12, 11, 10, 9, 8],
srcValuesLess: [16, 15],
srcValuesLessMultiple: [16, 15, 14, 13, 12, 11],
srcValuesMoreMultiple: [16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2],
srcValuesNonMultiple: [16, 15, 14, 13, 12, 11, 10, 9, 8, 7],
},
{ type: 'uvec4',
jsTypeOf: 'Uint32Array',
setter: 'uniform4uiv',
elem: '[3]',
numSrcValues: 3,
invalidSet: function(loc) {
gl.uniform1uiv(loc, [2]);
},
illegalSet: function(loc) {
gl.uniform1uiv(loc, 2);
},
srcValueAsString: function(index, srcValues) {
return "[" + srcValues[index * 4 + 0].toString() + ", " +
srcValues[index * 4 + 1].toString() + ", " +
srcValues[index * 4 + 2].toString() + ", " +
srcValues[index * 4 + 3].toString() + "]";
},
returnValueAsString: function(value) {
return value === null ? 'null' :
("[" + value[0] + ", " + value[1] +
", " + value[2] + ", " + value[3] + "]");
},
checkType: function(value) {
return value &&
typeof value.length === 'number' &&
value.length == 4;
},
checkValue: function(typeInfo, index, value) {
return value !== null &&
typeInfo.srcValues[index * 4 + 0] == value[0] &&
typeInfo.srcValues[index * 4 + 1] == value[1] &&
typeInfo.srcValues[index * 4 + 2] == value[2] &&
typeInfo.srcValues[index * 4 + 3] == value[3];
},
srcValues: [16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5],
srcValuesLess: [16, 15, 14],
srcValuesLessMultiple: [16, 15, 14, 13, 12, 11, 10, 9],
srcValuesMoreMultiple: [16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1],
srcValuesNonMultiple: [16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4],
},
{ type: 'bool',
jsTypeOf: 'boolean',
setter: 'uniform1iv',
elem: '',
numSrcValues: 3,
invalidSet: function(loc) {
gl.uniform2iv(loc, [1, 2]);
},
srcValueAsString: function(index, srcValues) {
return srcValues[index].toString();
},
returnValueAsString: function(value) {
return value === null ? 'null' : value.toString();
},
checkType: function(value) {
return typeof value === 'boolean';
},
checkValue: function(typeInfo, index, value) {
return typeInfo.srcValues[index] == value;
},
srcValues: [true, true, true],
srcValuesLess: [],
srcValuesLessMultiple: [16],
srcValuesMoreMultiple: [16, 15, 14, 13],
srcValuesNonMultiple: null,
},
{ type: 'bvec2',
jsTypeOf: 'Float32Array',
setter: 'uniform2fv',
elem: '[1]',
numSrcValues: 3,
invalidSet: function(loc) {
gl.uniform1iv(loc, [2]);
},
illegalSet: function(loc) {
gl.uniform1iv(loc, 2);
},
srcValueAsString: function(index, srcValues) {
return "[" + srcValues[index * 2 + 0].toString() + ", " +
srcValues[index * 2 + 1].toString() + "]";
},
returnValueAsString: function(value) {
return value === null ? 'null' : ("[" + value[0] + ", " + value[1] + "]");
},
checkType: function(value) {
return value &&
typeof value.length === 'number' &&
value.length == 2;
},
checkValue: function(typeInfo, index, value) {
return value !== null &&
typeInfo.srcValues[index * 2 + 0] == value[0] &&
typeInfo.srcValues[index * 2 + 1] == value[1];
},
srcValues: [true, true, true, true, true, true],
srcValuesLess: [16],
srcValuesLessMultiple: [16, 15, 14, 13],
srcValuesMoreMultiple: [16, 15, 14, 13, 12, 11, 10, 9],
srcValuesNonMultiple: [16, 15, 14, 13, 12, 11, 10],
},
{ type: 'bvec3',
jsTypeOf: 'Int32Array',
setter: 'uniform3iv',
elem: '[2]',
numSrcValues: 3,
invalidSet: function(loc) {
gl.uniform1iv(loc, [2]);
},
illegalSet: function(loc) {
gl.uniform1iv(loc, 2);
},
srcValueAsString: function(index, srcValues) {
return "[" + srcValues[index * 3 + 0].toString() + ", " +
srcValues[index * 3 + 1].toString() + ", " +
srcValues[index * 3 + 2].toString() + "]";
},
returnValueAsString: function(value) {
return value === null ? 'null' :
("[" + value[0] + ", " + value[1] + ", " + value[2] + "]");
},
checkType: function(value) {
return value &&
typeof value.length === 'number' &&
value.length == 3;
},
checkValue: function(typeInfo, index, value) {
return value !== null &&
typeInfo.srcValues[index * 3 + 0] == value[0] &&
typeInfo.srcValues[index * 3 + 1] == value[1] &&
typeInfo.srcValues[index * 3 + 2] == value[2];
},
srcValues: [true, true, true, true, true, true, true, true, true],
srcValuesLess: [16, 15],
srcValuesLessMultiple: [16, 15, 14, 13, 12, 11],
srcValuesMoreMultiple: [16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2],
srcValuesNonMultiple: [16, 15, 14, 13, 12, 11, 10, 9, 8, 7],
},
{ type: 'bvec4',
jsTypeOf: 'Uint32Array',
setter: 'uniform4uiv',
elem: '[3]',
numSrcValues: 3,
invalidSet: function(loc) {
gl.uniform1iv(loc, [2]);
},
illegalSet: function(loc) {
gl.uniform1iv(loc, 2);
},
srcValueAsString: function(index, srcValues) {
return "[" + srcValues[index * 4 + 0].toString() + ", " +
srcValues[index * 4 + 1].toString() + ", " +
srcValues[index * 4 + 2].toString() + ", " +
srcValues[index * 4 + 3].toString() + "]";
},
returnValueAsString: function(value) {
return value === null ? 'null' :
("[" + value[0] + ", " + value[1] +
", " + value[2] + ", " + value[3] + "]");
},
checkType: function(value) {
return value &&
typeof value.length === 'number' &&
value.length == 4;
},
checkValue: function(typeInfo, index, value) {
return value !== null &&
typeInfo.srcValues[index * 4 + 0] == value[0] &&
typeInfo.srcValues[index * 4 + 1] == value[1] &&
typeInfo.srcValues[index * 4 + 2] == value[2] &&
typeInfo.srcValues[index * 4 + 3] == value[3];
},
srcValues: [true, true, true, true, true, true, true, true, true, true, true, true],
srcValuesLess: [16, 15, 14],
srcValuesLessMultiple: [16, 15, 14, 13, 12, 11, 10, 9],
srcValuesMoreMultiple: [16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1],
srcValuesNonMultiple: [16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4],
}
];
typeInfos.push(...more);
}
let loc;
for (var tt = 0; tt < typeInfos.length; ++tt) { for (var tt = 0; tt < typeInfos.length; ++tt) {
var typeInfo = typeInfos[tt]; var typeInfo = typeInfos[tt];
debug(""); debug("");
@ -647,8 +199,7 @@ for (var tt = 0; tt < typeInfos.length; ++tt) {
assertMsg(info.name == "color[0]", assertMsg(info.name == "color[0]",
"uniform name is 'color[0]' not 'color' as per OpenGL ES 2.0.24 section 2.10"); "uniform name is 'color[0]' not 'color' as per OpenGL ES 2.0.24 section 2.10");
shouldBeNull("gl.getUniformLocation(program, 'color[" + MaxInt32PlusOne + "]');"); shouldBeNull("gl.getUniformLocation(program, 'color[" + MaxInt32PlusOne + "]');");
loc = gl.getUniformLocation(program, "color[0]"); var loc = gl.getUniformLocation(program, "color[0]");
if (!loc) throw 'Missing loc';
var srcValues = typeInfo.srcValues; var srcValues = typeInfo.srcValues;
var srcValuesLess = typeInfo.srcValuesLess; var srcValuesLess = typeInfo.srcValuesLess;
var srcValuesLessMultiple = typeInfo.srcValuesLessMultiple; var srcValuesLessMultiple = typeInfo.srcValuesLessMultiple;
@ -669,20 +220,6 @@ for (var tt = 0; tt < typeInfos.length; ++tt) {
wtu.glErrorShouldBe(gl, gl.INVALID_VALUE, wtu.glErrorShouldBe(gl, gl.INVALID_VALUE,
"should fail with non-multiple array size with gl." + typeInfo.setter); "should fail with non-multiple array size with gl." + typeInfo.setter);
} }
const validDatas = [
`new Float32Array(${srcValues.length})`,
`new Float32Array(new ArrayBuffer(4*${srcValues.length}))`,
];
if (window.SharedArrayBuffer) {
validDatas.push(
`new Float32Array(new SharedArrayBuffer(4*${srcValues.length}))`
);
}
for (const x of validDatas) {
shouldNotThrow(`gl.${typeInfo.setter}(loc, ${x});`);
}
gl[typeInfo.setter](loc, srcValues); gl[typeInfo.setter](loc, srcValues);
wtu.glErrorShouldBe(gl, gl.NO_ERROR, wtu.glErrorShouldBe(gl, gl.NO_ERROR,
"can set an array of uniforms with gl." + typeInfo.setter); "can set an array of uniforms with gl." + typeInfo.setter);
@ -697,7 +234,7 @@ for (var tt = 0; tt < typeInfos.length; ++tt) {
wtu.glErrorShouldBe(gl, gl.NO_ERROR, wtu.glErrorShouldBe(gl, gl.NO_ERROR,
"can call gl.getUniform"); "can call gl.getUniform");
assertMsg(typeInfo.checkType(values), assertMsg(typeInfo.checkType(values),
"gl.getUniform returns the correct type. " + `(was ${values.constructor.name})`); "gl.getUniform returns the correct type.");
for (var ii = 0; ii < typeInfo.numSrcValues; ++ii) { for (var ii = 0; ii < typeInfo.numSrcValues; ++ii) {
shouldBeNull("gl.getUniformLocation(program, 'color[" + (MaxInt32PlusOne + ii) + "]')"); shouldBeNull("gl.getUniformLocation(program, 'color[" + (MaxInt32PlusOne + ii) + "]')");
var elemLoc = gl.getUniformLocation(program, "color[" + ii + "]"); var elemLoc = gl.getUniformLocation(program, "color[" + ii + "]");

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

@ -19,49 +19,23 @@ found in the LICENSE.txt file.
<canvas id="example" width="2" height="2"> </canvas> <canvas id="example" width="2" height="2"> </canvas>
<script id="vshader" type="x-shader/x-vertex"> <script id="vshader" type="x-shader/x-vertex">
uniform mat2 world2x2; attribute vec4 vPosition;
uniform mat3 world3x3; uniform mat4 world4;
uniform mat4 world4x4; uniform mat3 world3;
void main() { uniform mat2 world2;
gl_Position.x += world2x2[0][0]; void main()
gl_Position.x += world3x3[0][0]; {
gl_Position.x += world4x4[0][0]; gl_Position = vec4(vPosition.xyz, world3[0].x + world2[0].x) * world4;
} }
</script> </script>
<script id="fshader" type="x-shader/x-fragment"> <script id="fshader" type="x-shader/x-fragment">
void main() {} void main()
</script> {
gl_FragColor = vec4(1.0,0.0,0.0,1.0);
<script id="vshader300" type="x-shader/x-vertex">
#version 300 es
uniform mat2 world2x2;
uniform mat2x3 world2x3;
uniform mat2x4 world2x4;
uniform mat3x2 world3x2;
uniform mat3 world3x3;
uniform mat3x4 world3x4;
uniform mat4x2 world4x2;
uniform mat4x3 world4x3;
uniform mat4 world4x4;
void main() {
gl_Position.x += world2x2[0][0];
gl_Position.x += world2x3[0][0];
gl_Position.x += world2x4[0][0];
gl_Position.x += world3x2[0][0];
gl_Position.x += world3x3[0][0];
gl_Position.x += world3x4[0][0];
gl_Position.x += world4x2[0][0];
gl_Position.x += world4x3[0][0];
gl_Position.x += world4x4[0][0];
} }
</script> </script>
<script id="fshader300" type="x-shader/x-fragment">
#version 300 es
void main() {}
</script>
<script> <script>
"use strict"; "use strict";
description("This test ensures WebGL implementations handle uniformMatrix in a OpenGL ES 2.0 spec compliant way"); description("This test ensures WebGL implementations handle uniformMatrix in a OpenGL ES 2.0 spec compliant way");
@ -72,42 +46,20 @@ debug("Checking gl.uniformMatrix.");
var wtu = WebGLTestUtils; var wtu = WebGLTestUtils;
var gl = wtu.create3DContext("example"); var gl = wtu.create3DContext("example");
var contextVersion = wtu.getDefault3DContextVersion(); var contextVersion = wtu.getDefault3DContextVersion();
var program = wtu.setupProgram(gl, ["vshader", "fshader"], ["vPosition"]);
let shaders = ["vshader", "fshader"]; for (var ii = 2; ii <= 4; ++ii) {
const dims = [ var loc = gl.getUniformLocation(program, "world" + ii);
[2, 2, 'uniformMatrix2fv'], var matLess = [];
[3, 3, 'uniformMatrix3fv'], for (var jj = 0; jj < ii; ++jj) {
[4, 4, 'uniformMatrix4fv'], for (var ll = 0; ll < ii; ++ll) {
]; if (jj == ii - 1 && ll == ii - 1)
continue;
if (contextVersion >= 2) { matLess[jj * ii + ll] = (jj == ll) ? 1 : 0;
shaders = ["vshader300", "fshader300"];
dims.push(
[2, 3, 'uniformMatrix2x3fv'],
[2, 4, 'uniformMatrix2x4fv'],
[3, 2, 'uniformMatrix3x2fv'],
[3, 4, 'uniformMatrix3x4fv'],
[4, 2, 'uniformMatrix4x2fv'],
[4, 3, 'uniformMatrix4x3fv']
);
}
const program = wtu.setupProgram(gl, shaders);
let loc;
for (const [A, B, name] of dims) {
loc = gl.getUniformLocation(program, `world${A}x${B}`);
if (!loc) throw 'missing loc';
const mat = [];
for (let a = 0; a < A; ++a) {
for (let b = 0; b < B; ++b) {
mat.push((a == b) ? 1 : 0);
} }
} }
const matLess = mat.slice(0, mat.length-2); var mat = matLess.concat([1]);
const matMore = mat.concat([1]); var matMore = mat.concat([1]);
name = "uniformMatrix" + ii + "fv";
gl[name](loc, false, matLess); gl[name](loc, false, matLess);
wtu.glErrorShouldBe(gl, gl.INVALID_VALUE, "should fail with insufficient array size for " + name); wtu.glErrorShouldBe(gl, gl.INVALID_VALUE, "should fail with insufficient array size for " + name);
gl[name](loc, false, mat); gl[name](loc, false, mat);
@ -115,19 +67,7 @@ for (const [A, B, name] of dims) {
gl[name](loc, false, matMore); gl[name](loc, false, matMore);
wtu.glErrorShouldBe(gl, gl.INVALID_VALUE, "should fail with more than 1 array size for " + name); wtu.glErrorShouldBe(gl, gl.INVALID_VALUE, "should fail with more than 1 array size for " + name);
const validDatas = [ mat[ii * ii - 1] = 1;
`new Float32Array(${mat.length})`,
`new Float32Array(new ArrayBuffer(4*${mat.length}))`,
];
if (window.SharedArrayBuffer) {
validDatas.push(
`new Float32Array(new SharedArrayBuffer(4*${mat.length}))`
);
}
for (const x of validDatas) {
shouldNotThrow(`gl.${name}(loc, false, ${x});`);
}
gl[name](loc, false, mat); gl[name](loc, false, mat);
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "can call " + name + "with transpose = false"); wtu.glErrorShouldBe(gl, gl.NO_ERROR, "can call " + name + "with transpose = false");
if (contextVersion <= 1) { if (contextVersion <= 1) {

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

@ -16,8 +16,8 @@ found in the LICENSE.txt file.
<body> <body>
<div id="description"></div> <div id="description"></div>
<div id="console"></div> <div id="console"></div>
<canvas id="canvas1" style="width: 50px; height: 50px;"> </canvas> <canvas id="canvas" style="width: 50px; height: 50px;"> </canvas>
<canvas id="canvas2" style="width: 50px; height: 50px;"> </canvas> <canvas id="canvas2d" width="40" height="40"> </canvas>
<script> <script>
"use strict"; "use strict";
description("This test ensures WebGL2 implementations interact correctly with the canvas tag."); description("This test ensures WebGL2 implementations interact correctly with the canvas tag.");
@ -25,53 +25,24 @@ description("This test ensures WebGL2 implementations interact correctly with th
debug(""); debug("");
debug("Canvas.getContext"); debug("Canvas.getContext");
function runTest() { assertMsg(window.WebGLRenderingContext,
assertMsg(window.WebGL2RenderingContext,
"WebGL2RenderingContext should be a member of window"); "WebGL2RenderingContext should be a member of window");
assertMsg('WebGL2RenderingContext' in window, assertMsg('WebGL2RenderingContext' in window,
"WebGL2RenderingContext should be 'in' window"); "WebGL2RenderingContext should be 'in' window");
const wtu = WebGLTestUtils; var wtu = WebGLTestUtils;
let canvas2 = document.getElementById("canvas2"); var canvas = document.getElementById("canvas");
let gl2 = wtu.create3DContext(canvas2, null, 2); var gl = wtu.create3DContext(canvas, null, 2);
if (!gl2) { if (!gl) {
testFailed("Could not fetch WebGL 2.0 context"); testFailed("context does not exist");
return; } else {
} testPassed("context exists");
testPassed("Fetched WebGL2 context successfully");
debug("Checking WebGL2 context type"); debug("Checking context type");
assertMsg(gl2 instanceof WebGL2RenderingContext, assertMsg(gl instanceof WebGL2RenderingContext,
"context type should be WebGL2RenderingContext"); "context type should be WebGL2RenderingContext");
// WebGL1 contexts do not respond to the WebGL2 context type, and vice versa.
let canvas1 = document.getElementById("canvas1");
let gl1 = wtu.create3DContext(canvas1, null, 1);
if (!gl1) {
testFailed("Could not fetch WebGL 1.0 context");
return;
}
debug("Checking WebGL1 context type");
assertMsg(gl1 instanceof WebGLRenderingContext,
"context type should be WebGLRenderingContext");
let msg1 = "A canvas which has created a WebGL 1.0 context should not return it for a 'webgl2' context request";
if (canvas1.getContext("webgl2"))
testFailed(msg1);
else
testPassed(msg1);
let msg2 = "A canvas which has created a WebGL 2.0 context should not return it for a 'webgl' context request";
if (canvas2.getContext("webgl"))
testFailed(msg2);
else
testPassed(msg2);
} }
runTest();
debug(""); debug("");
var successfullyParsed = true; var successfullyParsed = true;
</script> </script>
<script src="../../js/js-test-post.js"></script> <script src="../../js/js-test-post.js"></script>

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

@ -11,7 +11,6 @@ found in the LICENSE.txt file.
<link rel="stylesheet" href="../../resources/js-test-style.css"/> <link rel="stylesheet" href="../../resources/js-test-style.css"/>
<script src="../../js/js-test-pre.js"></script> <script src="../../js/js-test-pre.js"></script>
<script src="../../js/webgl-test-utils.js"></script> <script src="../../js/webgl-test-utils.js"></script>
<script src="../../js/tests/context-methods.js"></script>
</head> </head>
<body> <body>
<div id="description"></div> <div id="description"></div>
@ -21,7 +20,7 @@ found in the LICENSE.txt file.
"use strict"; "use strict";
description("This test ensures that the WebGL context has all the methods in the specification."); description("This test ensures that the WebGL context has all the methods in the specification.");
const methods = [ var methods = [
"getContextAttributes", "getContextAttributes",
"activeTexture", "activeTexture",
"attachShader", "attachShader",
@ -250,14 +249,55 @@ const methods = [
"bindVertexArray", "bindVertexArray",
]; ];
// Properties to be ignored because they were added in versions of the
// spec that are backward-compatible with this version
var ignoredMethods = [
// There is no official spec for the commit API yet, the proposal link is:
// https://wiki.whatwg.org/wiki/OffscreenCanvas
"commit"
];
function assertFunction(v, f) {
try {
if (typeof v[f] != "function") {
testFailed("Property either does not exist or is not a function: " + f);
return false;
} else {
return true;
}
} catch(e) {
testFailed("Trying to access the property '" + f + "' threw an error: "+e.toString());
}
}
debug(""); debug("");
debug("Canvas.getContext"); debug("Canvas.getContext");
const wtu = WebGLTestUtils; var wtu = WebGLTestUtils;
const canvas = document.getElementById("canvas"); var canvas = document.getElementById("canvas");
const gl = wtu.create3DContext(canvas, null, 2); var gl = wtu.create3DContext(canvas, null, 2);
var passed = true;
for (var i=0; i<methods.length; i++) {
var r = assertFunction(gl, methods[i]);
passed = passed && r;
}
if (passed) {
testPassed("All WebGL methods found.");
}
var extended = false;
for (var i in gl) {
if (typeof gl[i] == "function" && methods.indexOf(i) == -1 && ignoredMethods.indexOf(i) == -1) {
if (!extended) {
extended = true;
testFailed("Also found the following extra methods:");
}
testFailed(i);
}
}
testContextMethods(gl, methods); if (!extended) {
testPassed("No extra methods found on WebGL context.");
}
debug(""); debug("");
var successfullyParsed = true; var successfullyParsed = true;

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

@ -1,11 +1,9 @@
ext-color-buffer-float.html ext-color-buffer-float.html
--min-version 2.0.1 ext-color-buffer-half-float.html
ext-disjoint-timer-query-webgl2.html ext-disjoint-timer-query-webgl2.html
--min-version 2.0.1 ext-texture-filter-anisotropic.html --min-version 2.0.1 ext-texture-filter-anisotropic.html
--min-version 2.0.1 ext-texture-norm16.html --min-version 2.0.1 ext-texture-norm16.html
promoted-extensions.html promoted-extensions.html
promoted-extensions-in-shaders.html promoted-extensions-in-shaders.html
--min-version 2.0.1 oes-draw-buffers-indexed.html
--min-version 2.0.1 ovr_multiview2.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_depth.html
--min-version 2.0.1 ovr_multiview2_draw_buffers.html --min-version 2.0.1 ovr_multiview2_draw_buffers.html

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

@ -284,7 +284,7 @@ function runInternalFormatQueryTest()
debug("testing the internal format query"); debug("testing the internal format query");
var maxSamples = gl.getParameter(gl.MAX_SAMPLES); var maxSamples = gl.getParameter(gl.MAX_SAMPLES);
const formats = [gl.RGBA16F, gl.R32F, gl.RG32F, gl.RGBA32F, gl.R16F, gl.RG16F, gl.R11F_G11F_B10F]; var formats = new Array(gl.RGBA16F, gl.R32F, gl.RG32F, gl.RGBA32F, gl.R16F, gl.RG16F, gl.R11F_G11F_B10F);
var firstMultiOnlyFormat = 4; var firstMultiOnlyFormat = 4;
for (var fmt = 0; fmt < formats.length; ++fmt) { for (var fmt = 0; fmt < formats.length; ++fmt) {
var samples = gl.getInternalformatParameter(gl.RENDERBUFFER, formats[fmt], gl.SAMPLES); var samples = gl.getInternalformatParameter(gl.RENDERBUFFER, formats[fmt], gl.SAMPLES);

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

@ -1,27 +0,0 @@
<!--
Copyright (c) 2020 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">
<title>WebGL 2 EXT_color_buffer_half_float Conformance Tests</title>
<link rel="stylesheet" href="../../resources/js-test-style.css"/>
<script src="../../js/js-test-pre.js"></script>
<script src="../../js/webgl-test-utils.js"></script>
</head> 
<body>
<div id="description"></div>
<canvas id="canvas" style="width: 50px; height: 50px;"> </canvas>
<div id="console"></div>
<script>
var version = 2;
</script>
<script src="../../js/tests/ext-color-buffer-half-float.js"></script>
<script src="../../js/js-test-post.js"></script>
</body>
</html>

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

@ -23,7 +23,7 @@ description("This test verifies the functionality of the EXT_texture_norm16 exte
debug(""); debug("");
var wtu = WebGLTestUtils; var wtu = WebGLTestUtils;
var gl = wtu.create3DContext(null, null, 2); var gl = wtu.create3DContext();
var ext; var ext;
var formats = null; var formats = null;
@ -138,38 +138,6 @@ function testNorm16Render(interalFormat, format, type, tolerance) {
gl.bindTexture(gl.TEXTURE_2D, null); gl.bindTexture(gl.TEXTURE_2D, null);
} }
function testSnorm16Unrenderable(internalFormat, format, type) {
gl.bindTexture(gl.TEXTURE_2D, textures[1]);
gl.texImage2D(gl.TEXTURE_2D, 0, internalFormat, 1, 1, 0, format, type, null);
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "texture definition succeeded");
gl.bindFramebuffer(gl.FRAMEBUFFER, fbos[0]);
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, textures[1], 0);
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "fbo binding succeeded");
wtu.framebufferStatusShouldBe(gl, gl.FRAMEBUFFER, [ gl.FRAMEBUFFER_INCOMPLETE_ATTACHMENT, gl.FRAMEBUFFER_UNSUPPORTED ],
"framebuffer should not be complete with SNORM16 texture attached");
}
function runInternalFormatQueryTest()
{
debug("");
debug("testing the internal format query");
var maxSamples = gl.getParameter(gl.MAX_SAMPLES);
const formats = [ext.R16_EXT, ext.RG16_EXT, ext.RGBA16_EXT];
for (const format of formats) {
var samples = gl.getInternalformatParameter(gl.RENDERBUFFER, format, gl.SAMPLES);
if (samples == null || samples.length == 0 || samples[0] < maxSamples) {
testFailed("the maximum value in SAMPLES should be at least " + maxSamples);
return;
}
}
testPassed("Internal format query succeeded");
}
function runTestExtension() { function runTestExtension() {
textures = [gl.createTexture(), gl.createTexture()]; textures = [gl.createTexture(), gl.createTexture()];
fbos = [gl.createFramebuffer(), gl.createFramebuffer()]; fbos = [gl.createFramebuffer(), gl.createFramebuffer()];
@ -206,11 +174,6 @@ function runTestExtension() {
testNorm16Render(ext.R16_EXT, gl.RED, gl.UNSIGNED_SHORT, 0); testNorm16Render(ext.R16_EXT, gl.RED, gl.UNSIGNED_SHORT, 0);
testNorm16Render(ext.RG16_EXT, gl.RG, gl.UNSIGNED_SHORT, 0); testNorm16Render(ext.RG16_EXT, gl.RG, gl.UNSIGNED_SHORT, 0);
testNorm16Render(ext.RGBA16_EXT, gl.RGBA, gl.UNSIGNED_SHORT, 0); testNorm16Render(ext.RGBA16_EXT, gl.RGBA, gl.UNSIGNED_SHORT, 0);
testSnorm16Unrenderable(ext.R16_SNORM_EXT, gl.RED, gl.SHORT);
testSnorm16Unrenderable(ext.RG16_SNORM_EXT, gl.RG, gl.SHORT);
testSnorm16Unrenderable(ext.RGB16_SNORM_EXT, gl.RGB, gl.SHORT);
testSnorm16Unrenderable(ext.RGBA16_SNORM_EXT, gl.RGBA, gl.SHORT);
}; };
function runTest() { function runTest() {
@ -224,7 +187,6 @@ function runTest() {
wtu.runExtensionSupportedTest(gl, "EXT_texture_norm16", ext !== null); wtu.runExtensionSupportedTest(gl, "EXT_texture_norm16", ext !== null);
if (ext !== null) { if (ext !== null) {
runInternalFormatQueryTest();
runTestExtension(); runTestExtension();
} else { } else {
testPassed("No EXT_texture_norm16 support -- this is legal"); testPassed("No EXT_texture_norm16 support -- this is legal");

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

@ -1,545 +0,0 @@
<!--
Copyright (c) 2020 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">
<title>WebGL OES_draw_buffers_indexed Conformance Tests</title>
<LINK rel="stylesheet" href="../../resources/js-test-style.css"/>
<script src="../../js/js-test-pre.js"></script>
<script src="../../js/webgl-test-utils.js"></script>
</head>
<body>
<div id="description"></div>
<div id="console"></div>
<script>
"use strict";
description("This test verifies the functionality of the OES_draw_buffers_indexed extension, if it is available.");
debug("");
var wtu = WebGLTestUtils;
var canvas = document.getElementById("canvas");
var gl = wtu.create3DContext(null, null, 2);
var ext;
const vs = `#version 300 es
layout(location=0) in vec4 vPosition;
void main()
{
gl_Position = vPosition;
}
`;
const fs = `#version 300 es
precision lowp float;
layout(location = 0) out vec4 o_color0;
layout(location = 1) out vec4 o_color1;
void main()
{
o_color0 = vec4(1, 0, 0, 0);
o_color1 = vec4(1, 0, 0, 0);
}
`;
function setup() {
const program = wtu.setupProgram(gl, [vs, fs]);
gl.useProgram(program);
wtu.setupUnitQuad(gl, 0);
wtu.glErrorShouldBe(gl, 0, 'No errors from program');
const tex1 = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, tex1);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
wtu.glErrorShouldBe(gl, 0, 'Create texture 1 successfully');
const tex2 = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, tex2);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
wtu.glErrorShouldBe(gl, 0, 'Create texture 2 successfully');
const attachments = [gl.COLOR_ATTACHMENT0, gl.COLOR_ATTACHMENT1];
const fb = gl.createFramebuffer();
gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
gl.framebufferTexture2D(gl.FRAMEBUFFER, attachments[0], gl.TEXTURE_2D, tex1, 0);
gl.framebufferTexture2D(gl.FRAMEBUFFER, attachments[1], gl.TEXTURE_2D, tex2, 0);
shouldBe('gl.checkFramebufferStatus(gl.FRAMEBUFFER)', 'gl.FRAMEBUFFER_COMPLETE');
gl.drawBuffers(attachments);
wtu.glErrorShouldBe(gl, 0, 'Set draw buffers without errors');
}
function enableDisableTest() {
debug("Testing enableiOES/disableiOES");
// Invalid input
ext.enableiOES(gl.DEPTH_TEST, 0);
wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, 'target could only be gl.BLEND');
ext.disableiOES(gl.DEPTH_TEST, 0);
wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, 'target could only be gl.BLEND');
gl.disable(gl.BLEND);
// Valid input
ext.enableiOES(gl.BLEND, 0);
shouldBe('gl.isEnabled(gl.BLEND)', 'true');
ext.disableiOES(gl.BLEND, 0);
ext.enableiOES(gl.BLEND, 1);
shouldBe('gl.isEnabled(gl.BLEND)', 'false');
gl.enable(gl.BLEND);
shouldBe('gl.isEnabled(gl.BLEND)', 'true');
wtu.glErrorShouldBe(gl, 0, 'No errors from enable and disable draw buffers blend state');
}
function constantAlphaBlendColorValidationTest() {
debug("Testing CONSTANT_COLOR/ALPHA blend functions limit validation");
function isConstantColorAndAlphaBlendFunctions(first, second)
{
return (first == gl.CONSTANT_COLOR || first == gl.ONE_MINUS_CONSTANT_COLOR) &&
(second == gl.CONSTANT_ALPHA || second == gl.ONE_MINUS_CONSTANT_ALPHA);
}
function checkBlendFunctions(src, dst)
{
if (isConstantColorAndAlphaBlendFunctions(src, dst) ||
isConstantColorAndAlphaBlendFunctions(dst, src))
{
wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, 'invalid combinations');
return false;
}
else
{
wtu.glErrorShouldBe(gl, 0, 'No error');
return true;
}
}
const srcFunc = [
gl.ZERO,
gl.ONE,
gl.SRC_COLOR,
gl.ONE_MINUS_SRC_COLOR,
gl.DST_COLOR,
gl.ONE_MINUS_DST_COLOR,
gl.SRC_ALPHA,
gl.ONE_MINUS_SRC_ALPHA,
gl.DST_ALPHA,
gl.ONE_MINUS_DST_ALPHA,
gl.CONSTANT_COLOR,
gl.ONE_MINUS_CONSTANT_COLOR,
gl.CONSTANT_ALPHA,
gl.ONE_MINUS_CONSTANT_ALPHA,
gl.SRC_ALPHA_SATURATE,
];
const dstFunc = [
gl.ZERO, gl.ONE,
gl.SRC_COLOR, gl.ONE_MINUS_SRC_COLOR,
gl.DST_COLOR, gl.ONE_MINUS_DST_COLOR,
gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA,
gl.DST_ALPHA, gl.ONE_MINUS_DST_ALPHA,
gl.CONSTANT_COLOR, gl.ONE_MINUS_CONSTANT_COLOR,
gl.CONSTANT_ALPHA, gl.ONE_MINUS_CONSTANT_ALPHA,
];
let src, dst;
// CONSTANT_COLOR/ALPHA invalid combination check
for (let i = 0, leni = srcFunc.length; i < leni; i++)
{
src = srcFunc[i];
for (let j = 0, lenj = dstFunc.length; j < lenj; j++)
{
dst = dstFunc[j];
ext.blendFunciOES(0, src, dst);
checkBlendFunctions(src, dst);
ext.blendFuncSeparateiOES(0, src, dst, gl.ONE, gl.ONE);
checkBlendFunctions(src, dst);
}
}
}
function indexedBlendColorTest() {
debug('');
debug("Testing blendEquationiOES and blendFunciOES");
wtu.glErrorShouldBe(gl, 0, 'top of indexedBlendColorTest');
gl.clearColor(0, 0, 1, 1);
gl.clear(gl.COLOR_BUFFER_BIT);
ext.blendEquationiOES(0, gl.FUNC_ADD);
ext.blendFunciOES(0, gl.ONE, gl.ONE);
ext.blendEquationiOES(1, gl.FUNC_ADD);
ext.blendFunciOES(1, gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
gl.drawArrays(gl.TRIANGLES, 0, 6);
wtu.glErrorShouldBe(gl, 0, 'Draw quad without errors');
gl.readBuffer(gl.COLOR_ATTACHMENT0);
wtu.checkCanvasRect(gl, 0, 0, 1, 1, [255, 0, 255, 255]);
gl.readBuffer(gl.COLOR_ATTACHMENT1);
wtu.checkCanvasRect(gl, 0, 0, 1, 1, [0, 0, 255, 255]);
debug("Testing blendEquationSeparateiOES and blendFuncSeparateiOES");
gl.clear(gl.COLOR_BUFFER_BIT);
ext.blendEquationSeparateiOES(0, gl.FUNC_ADD, gl.FUNC_SUBTRACT);
ext.blendFuncSeparateiOES(0, gl.ONE, gl.ONE, gl.ZERO, gl.ZERO);
ext.blendEquationSeparateiOES(1, gl.FUNC_ADD, gl.FUNC_SUBTRACT);
ext.blendFuncSeparateiOES(1, gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA, gl.ZERO, gl.ZERO);
gl.drawArrays(gl.TRIANGLES, 0, 6);
wtu.glErrorShouldBe(gl, 0, 'Draw quad without errors');
gl.readBuffer(gl.COLOR_ATTACHMENT0);
wtu.checkCanvasRect(gl, 0, 0, 1, 1, [255, 0, 255, 0]);
gl.readBuffer(gl.COLOR_ATTACHMENT1);
wtu.checkCanvasRect(gl, 0, 0, 1, 1, [0, 0, 255, 0]);
debug("Testing colorMaskiOES");
gl.clear(gl.COLOR_BUFFER_BIT);
ext.colorMaskiOES(0, false, false, false, false);
ext.colorMaskiOES(1, true, true, true, true);
gl.drawArrays(gl.TRIANGLES, 0, 6);
wtu.glErrorShouldBe(gl, 0, 'Draw quad without errors');
gl.readBuffer(gl.COLOR_ATTACHMENT0);
wtu.checkCanvasRect(gl, 0, 0, 1, 1, [0, 0, 255, 255]);
gl.readBuffer(gl.COLOR_ATTACHMENT1);
wtu.checkCanvasRect(gl, 0, 0, 1, 1, [0, 0, 255, 0]);
debug('');
debug(`Testing that new tokens aren't on the extension.`);
shouldBe('ext.BLEND_EQUATION_RGB', 'undefined');
shouldBe('ext.BLEND_EQUATION_ALPHA', 'undefined');
shouldBe('ext.BLEND_SRC_RGB', 'undefined');
shouldBe('ext.BLEND_SRC_ALPHA', 'undefined');
shouldBe('ext.BLEND_DST_RGB', 'undefined');
shouldBe('ext.BLEND_DST_ALPHA', 'undefined');
shouldBe('ext.COLOR_WRITEMASK', 'undefined');
debug("Testing new tokens for getIndexedParameterTest");
shouldBe('gl.getIndexedParameter(gl.BLEND_EQUATION_RGB, 0)', 'gl.FUNC_ADD');
shouldBe('gl.getIndexedParameter(gl.BLEND_EQUATION_ALPHA, 0)', 'gl.FUNC_SUBTRACT');
shouldBe('gl.getIndexedParameter(gl.BLEND_SRC_RGB, 0)', 'gl.ONE');
shouldBe('gl.getIndexedParameter(gl.BLEND_DST_RGB, 0)', 'gl.ONE');
shouldBe('gl.getIndexedParameter(gl.BLEND_SRC_ALPHA, 0)', 'gl.ZERO');
shouldBe('gl.getIndexedParameter(gl.BLEND_DST_ALPHA, 0)', 'gl.ZERO');
shouldBe('gl.getIndexedParameter(gl.BLEND_EQUATION_RGB, 1)', 'gl.FUNC_ADD');
shouldBe('gl.getIndexedParameter(gl.BLEND_EQUATION_ALPHA, 1)', 'gl.FUNC_SUBTRACT');
shouldBe('gl.getIndexedParameter(gl.BLEND_SRC_RGB, 1)', 'gl.SRC_ALPHA');
shouldBe('gl.getIndexedParameter(gl.BLEND_DST_RGB, 1)', 'gl.ONE_MINUS_SRC_ALPHA');
shouldBe('gl.getIndexedParameter(gl.BLEND_SRC_ALPHA, 1)', 'gl.ZERO');
shouldBe('gl.getIndexedParameter(gl.BLEND_DST_ALPHA, 1)', 'gl.ZERO');
shouldBe('gl.getIndexedParameter(gl.COLOR_WRITEMASK, 0)', '[false, false, false, false]');
shouldBe('gl.getIndexedParameter(gl.COLOR_WRITEMASK, 1)', '[true, true, true, true]');
debug("Testing non-indexed getParamter get state from draw buffer 0");
shouldBe('gl.getParameter(gl.BLEND_SRC_RGB)', 'gl.ONE');
shouldBe('gl.getParameter(gl.BLEND_DST_RGB)', 'gl.ONE');
shouldBe('gl.getParameter(gl.BLEND_SRC_ALPHA)', 'gl.ZERO');
shouldBe('gl.getParameter(gl.BLEND_DST_ALPHA)', 'gl.ZERO');
shouldBe('gl.getParameter(gl.BLEND_EQUATION_RGB)', 'gl.FUNC_ADD');
shouldBe('gl.getParameter(gl.BLEND_EQUATION_ALPHA)', 'gl.FUNC_SUBTRACT');
shouldBe('gl.getParameter(gl.COLOR_WRITEMASK)', '[false, false, false, false]');
debug("Testing non-indexed calls modify all draw buffers state");
gl.blendEquationSeparate(gl.FUNC_SUBTRACT, gl.FUNC_ADD);
gl.blendFuncSeparate(gl.ONE_MINUS_DST_ALPHA, gl.DST_ALPHA, gl.ONE, gl.ONE);
gl.colorMask(true, false, true, false);
wtu.glErrorShouldBe(gl, 0, 'Non-indexed state set without errors');
shouldBe('gl.getParameter(gl.BLEND_EQUATION_RGB)', 'gl.FUNC_SUBTRACT');
shouldBe('gl.getParameter(gl.BLEND_EQUATION_ALPHA)', 'gl.FUNC_ADD');
shouldBe('gl.getParameter(gl.BLEND_SRC_RGB)', 'gl.ONE_MINUS_DST_ALPHA');
shouldBe('gl.getParameter(gl.BLEND_DST_RGB)', 'gl.DST_ALPHA');
shouldBe('gl.getParameter(gl.BLEND_SRC_ALPHA)', 'gl.ONE');
shouldBe('gl.getParameter(gl.BLEND_DST_ALPHA)', 'gl.ONE');
shouldBe('gl.getParameter(gl.COLOR_WRITEMASK)', '[true, false, true, false]');
shouldBe('gl.getIndexedParameter(gl.BLEND_EQUATION_RGB, 0)', 'gl.FUNC_SUBTRACT');
shouldBe('gl.getIndexedParameter(gl.BLEND_EQUATION_ALPHA, 0)', 'gl.FUNC_ADD');
shouldBe('gl.getIndexedParameter(gl.BLEND_SRC_RGB, 0)', 'gl.ONE_MINUS_DST_ALPHA');
shouldBe('gl.getIndexedParameter(gl.BLEND_DST_RGB, 0)', 'gl.DST_ALPHA');
shouldBe('gl.getIndexedParameter(gl.BLEND_SRC_ALPHA, 0)', 'gl.ONE');
shouldBe('gl.getIndexedParameter(gl.BLEND_DST_ALPHA, 0)', 'gl.ONE');
shouldBe('gl.getIndexedParameter(gl.BLEND_EQUATION_RGB, 1)', 'gl.FUNC_SUBTRACT');
shouldBe('gl.getIndexedParameter(gl.BLEND_EQUATION_ALPHA, 1)', 'gl.FUNC_ADD');
shouldBe('gl.getIndexedParameter(gl.BLEND_SRC_RGB, 1)', 'gl.ONE_MINUS_DST_ALPHA');
shouldBe('gl.getIndexedParameter(gl.BLEND_DST_RGB, 1)', 'gl.DST_ALPHA');
shouldBe('gl.getIndexedParameter(gl.BLEND_SRC_ALPHA, 1)', 'gl.ONE');
shouldBe('gl.getIndexedParameter(gl.BLEND_DST_ALPHA, 1)', 'gl.ONE');
shouldBe('gl.getIndexedParameter(gl.COLOR_WRITEMASK, 0)', '[true, false, true, false]');
shouldBe('gl.getIndexedParameter(gl.COLOR_WRITEMASK, 1)', '[true, false, true, false]');
}
function runTestExtension() {
setup();
testInvalidValues();
enableDisableTest();
// blending should be enabled for drawBuffers 0 and 1 at this point
constantAlphaBlendColorValidationTest();
indexedBlendColorTest();
testColorMaskDrawNoOp();
}
function runInvalidEnumsTest() {
debug("Testing new enums for getIndexedParameterTest being invalid before requesting the extension");
gl.getIndexedParameter(0x8009, 0); // BLEND_EQUATION_RGB
wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, 'BLEND_EQUATION_RGB');
gl.getIndexedParameter(0x883D, 0); // BLEND_EQUATION_ALPHA
wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, 'BLEND_EQUATION_ALPHA');
gl.getIndexedParameter(0x80C9, 0); // BLEND_SRC_RGB
wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, 'BLEND_SRC_RGB');
gl.getIndexedParameter(0x80CB, 0); // BLEND_SRC_ALPHA
wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, 'BLEND_SRC_ALPHA');
gl.getIndexedParameter(0x80C8, 0); // BLEND_DST_RGB
wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, 'BLEND_DST_RGB');
gl.getIndexedParameter(0x80CA, 0); // BLEND_DST_ALPHA
wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, 'BLEND_DST_ALPHA');
gl.getIndexedParameter(0x0C23, 0); // COLOR_WRITEMASK
wtu.glErrorShouldBe(gl, [gl.INVALID_OPERATION, gl.INVALID_ENUM], 'invalid operations or invalid enums for COLOR_WRITEMASK');
}
function testInvalidValues() {
const numDrawBuffers = gl.getParameter(gl.MAX_DRAW_BUFFERS);
if (!numDrawBuffers) throw new Error('!numDrawBuffers');
wtu.shouldGenerateGLError(gl, gl.INVALID_VALUE, `ext.enableiOES(gl.BLEND, -1)`);
wtu.shouldGenerateGLError(gl, gl.INVALID_VALUE, `ext.enableiOES(gl.BLEND, ${numDrawBuffers})`);
wtu.shouldGenerateGLError(gl, 0, `ext.enableiOES(gl.BLEND, ${numDrawBuffers-1})`);
wtu.shouldGenerateGLError(gl, gl.INVALID_VALUE, `ext.disableiOES(gl.BLEND, -1)`);
wtu.shouldGenerateGLError(gl, gl.INVALID_VALUE, `ext.disableiOES(gl.BLEND, ${numDrawBuffers})`);
wtu.shouldGenerateGLError(gl, 0, `ext.disableiOES(gl.BLEND, ${numDrawBuffers-1})`);
wtu.shouldGenerateGLError(gl, gl.INVALID_VALUE, `ext.blendEquationiOES(-1, gl.FUNC_ADD)`);
wtu.shouldGenerateGLError(gl, gl.INVALID_VALUE, `ext.blendEquationiOES(${numDrawBuffers}, gl.FUNC_ADD)`);
wtu.shouldGenerateGLError(gl, 0, `ext.blendEquationiOES(${numDrawBuffers-1}, gl.FUNC_ADD)`);
wtu.shouldGenerateGLError(gl, gl.INVALID_VALUE, `ext.blendEquationSeparateiOES(-1, gl.FUNC_ADD, gl.FUNC_ADD)`);
wtu.shouldGenerateGLError(gl, gl.INVALID_VALUE, `ext.blendEquationSeparateiOES(${numDrawBuffers}, gl.FUNC_ADD, gl.FUNC_ADD)`);
wtu.shouldGenerateGLError(gl, 0, `ext.blendEquationSeparateiOES(${numDrawBuffers-1}, gl.FUNC_ADD, gl.FUNC_ADD)`);
wtu.shouldGenerateGLError(gl, gl.INVALID_VALUE, `ext.blendFunciOES(-1, gl.ONE, gl.ONE)`);
wtu.shouldGenerateGLError(gl, gl.INVALID_VALUE, `ext.blendFunciOES(${numDrawBuffers}, gl.ONE, gl.ONE)`);
wtu.shouldGenerateGLError(gl, 0, `ext.blendFunciOES(${numDrawBuffers-1}, gl.ONE, gl.ONE)`);
wtu.shouldGenerateGLError(gl, gl.INVALID_VALUE, `ext.blendFuncSeparateiOES(-1, gl.ONE, gl.ZERO, gl.ONE, gl.ZERO)`);
wtu.shouldGenerateGLError(gl, gl.INVALID_VALUE, `ext.blendFuncSeparateiOES(${numDrawBuffers}, gl.ONE, gl.ZERO, gl.ONE, gl.ZERO)`);
wtu.shouldGenerateGLError(gl, 0, `ext.blendFuncSeparateiOES(${numDrawBuffers-1}, gl.ONE, gl.ZERO, gl.ONE, gl.ZERO)`);
wtu.shouldGenerateGLError(gl, gl.INVALID_VALUE, `ext.colorMaskiOES(-1, 1,1,1,1)`);
wtu.shouldGenerateGLError(gl, gl.INVALID_VALUE, `ext.colorMaskiOES(${numDrawBuffers}, 1,1,1,1)`);
wtu.shouldGenerateGLError(gl, 0, `ext.colorMaskiOES(${numDrawBuffers-1}, 1,1,1,1)`);
}
function* range(n) {
for (let i = 0; i < n; i++) {
yield i;
}
}
function testColorMaskDrawNoOp() {
debug('');
debug('testColorMaskDrawNoOp')
// > If any draw buffer with an attachment does not have a defined
// fragment shader output, draws generate INVALID_OPERATION,
// unless all 4 channels of colorMask are set to false.
const NUM_OUTPUTS = gl.getParameter(gl.MAX_COLOR_ATTACHMENTS);
shouldBeTrue(`${NUM_OUTPUTS} > 1`);
const fb = gl.createFramebuffer();
gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
gl.viewport(0,0,1,1);
const DRAW_BUFFERS = [];
for (const i of range(NUM_OUTPUTS)) {
const tex = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, tex);
gl.texStorage2D(gl.TEXTURE_2D, 1, gl.RGBA8, 1, 1);
const ca = gl.COLOR_ATTACHMENT0+i;
DRAW_BUFFERS.push(ca)
gl.framebufferTexture2D(gl.FRAMEBUFFER, ca,
gl.TEXTURE_2D, tex, 0);
}
shouldBe('gl.checkFramebufferStatus(gl.FRAMEBUFFER)', 'gl.FRAMEBUFFER_COMPLETE');
gl.drawBuffers(DRAW_BUFFERS);
console.log('DRAW_BUFFERS', DRAW_BUFFERS);
gl.clearColor(0, 0, 0, 0);
gl.clear(gl.COLOR_BUFFER_BIT);
for (const i of range(NUM_OUTPUTS)) {
gl.readBuffer(gl.COLOR_ATTACHMENT0+i);
wtu.checkCanvasRect(gl, 0, 0, 1, 1, [0, 0, 0, 0], 'initially black');
}
for (const validOutput of range(NUM_OUTPUTS)) {
const invalidOutput = validOutput ^ 0b11;
debug(`validOutput: ${validOutput}, invalidOutput: ${invalidOutput}`);
const prog = wtu.setupProgram(gl, [
`\
#version 300 es
void main() {
gl_Position = vec4(0,0,0,1);
gl_PointSize = 1.0f;
}
`,
`\
#version 300 es
precision mediump float;
layout(location=${validOutput}) out vec4 o_color;
void main() {
o_color = vec4(1,1,1,1);
}
`
]);
gl.useProgram(prog);
wtu.glErrorShouldBe(gl, gl.NO_ERROR,
'After init.');
gl.colorMask(1,1,1,1);
gl.drawBuffers(DRAW_BUFFERS);
gl.drawArrays(gl.POINTS, 0, 1);
wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION,
'Drawing with unmasked undefined color outputs.');
gl.colorMask(0,0,0,0);
gl.drawBuffers(DRAW_BUFFERS);
gl.drawArrays(gl.POINTS, 0, 1);
wtu.glErrorShouldBe(gl, gl.NO_ERROR,
'Drawing with colorMask-masked-out undefined color outputs.');
gl.colorMask(1,1,1,1);
gl.drawBuffers(DRAW_BUFFERS.map((x,i) => (i == invalidOutput) ? x : 0));
gl.drawArrays(gl.POINTS, 0, 1);
wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION,
'Drawing with wrong-id drawBuffer-masked-out undefined color outputs.');
gl.drawBuffers(DRAW_BUFFERS.map((x,i) => (i == validOutput) ? x : 0));
gl.drawArrays(gl.POINTS, 0, 1);
wtu.glErrorShouldBe(gl, gl.NO_ERROR,
'Drawing with drawBuffer-masked-out undefined color outputs.');
gl.colorMask(0,0,0,0);
gl.drawBuffers([]);
gl.drawArrays(gl.POINTS, 0, 1);
wtu.glErrorShouldBe(gl, gl.NO_ERROR,
'Drawing with colorMask+drawBuffer-masked-out undefined color outputs.');
const testMask = (r,g,b,a) => {
debug(`testMask(${[r,g,b,a]})`);
gl.drawBuffers(DRAW_BUFFERS);
gl.colorMask(1,1,1,1);
gl.clearColor(0, 0, 0, 0);
gl.clear(gl.COLOR_BUFFER_BIT);
gl.colorMask(0,0,0,0);
ext.colorMaskiOES(validOutput, r,g,b,a);
gl.drawArrays(gl.POINTS, 0, 1);
wtu.glErrorShouldBe(gl, gl.NO_ERROR,
`Drawing with sole defined color${validOutput} output writemask: ${[r,g,b,a]}.`);
for (const i of range(NUM_OUTPUTS)) {
gl.readBuffer(gl.COLOR_ATTACHMENT0+i);
let expect = [0,0,0,0];
if (i == validOutput) {
expect = [r,g,b,a].map(x => 0xff*x);
}
wtu.checkCanvasRect(gl, 0, 0, 1, 1, expect, `COLOR_ATTACHMENT${i}: [${expect}]`);
}
gl.colorMask(1,1,1,1);
gl.clearColor(0, 0, 0, 0);
gl.clear(gl.COLOR_BUFFER_BIT);
gl.colorMask(r,g,b,a);
for (const i of range(NUM_OUTPUTS)) {
if (i == validOutput) continue;
ext.colorMaskiOES(i, 0,0,0,0);
}
gl.drawArrays(gl.POINTS, 0, 1);
wtu.glErrorShouldBe(gl, gl.NO_ERROR,
`Drawing with sole remaining defined color${validOutput} output writemask: ${[r,g,b,a]}.`);
for (const i of range(NUM_OUTPUTS)) {
gl.readBuffer(gl.COLOR_ATTACHMENT0+i);
let expect = [0,0,0,0];
if (i == validOutput) {
expect = [r,g,b,a].map(x => 0xff*x);
}
wtu.checkCanvasRect(gl, 0, 0, 1, 1, expect, `COLOR_ATTACHMENT${i}: [${expect}]`);
}
if (r || g || b || a) {
gl.colorMask(0,0,0,0);
ext.colorMaskiOES(invalidOutput, r,g,b,a);
gl.drawArrays(gl.POINTS, 0, 1);
wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION,
`Drawing with wrong-id undefined color output color masked: ${[r,g,b,a]}.`);
gl.drawBuffers([]);
gl.drawArrays(gl.POINTS, 0, 1);
wtu.glErrorShouldBe(gl, gl.NO_ERROR,
'Drawing with wrong-id colorMask, but all-off drawBuffers.');
gl.drawBuffers(DRAW_BUFFERS.map((x,i) => (i == validOutput) ? x : 0));
gl.drawArrays(gl.POINTS, 0, 1);
wtu.glErrorShouldBe(gl, gl.NO_ERROR,
'Drawing with wrong-id colorMask, but right-id drawBuffers masked.');
}
};
testMask(0,0,0,0);
testMask(1,0,0,0);
testMask(0,1,0,0);
testMask(0,0,1,0);
testMask(0,0,0,1);
testMask(1,1,1,1);
}
}
function runTest() {
if (!gl) {
testFailed("context does not exist");
} else {
testPassed("context exists");
runInvalidEnumsTest();
ext = gl.getExtension("OES_draw_buffers_indexed");
wtu.runExtensionSupportedTest(gl, "OES_draw_buffers_indexed", ext !== null);
if (ext !== null) {
runTestExtension();
} else {
testPassed("No OES_draw_buffers_indexed support -- this is legal");
}
}
}
runTest();
var successfullyParsed = true;
</script>
<script src="../../js/js-test-post.js"></script>
</body>
</html>

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

@ -38,6 +38,7 @@ var exts = gl.getSupportedExtensions();
var promotedExtensions = [ var promotedExtensions = [
"ANGLE_instanced_arrays", "ANGLE_instanced_arrays",
"EXT_blend_minmax", "EXT_blend_minmax",
"EXT_color_buffer_half_float",
"EXT_frag_depth", "EXT_frag_depth",
"EXT_shader_texture_lod", "EXT_shader_texture_lod",
"EXT_sRGB", "EXT_sRGB",

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

@ -9,7 +9,7 @@
<script src="../../js/webgl-test-utils.js"></script> <script src="../../js/webgl-test-utils.js"></script>
</head> </head>
<body> <body>
<script id="vshaderBaseInstanceWithoutExt" type="x-shader/x-vertex">#version 300 es <script id="vshaderIllegalBaseInstance" type="x-shader/x-vertex">#version 300 es
layout(location = 0) in vec2 vPosition; layout(location = 0) in vec2 vPosition;
out vec4 color; out vec4 color;
void main() void main()
@ -18,6 +18,20 @@ void main()
gl_Position = vec4(vPosition * 2.0 - 1.0, gl_BaseInstance, 1); gl_Position = vec4(vPosition * 2.0 - 1.0, gl_BaseInstance, 1);
} }
</script> </script>
<script id="vshaderBaseInstanceZero" type="x-shader/x-vertex">#version 300 es
#extension GL_ANGLE_base_vertex_base_instance : require
layout(location = 0) in vec2 vPosition;
out vec4 color;
void main()
{
if (gl_BaseInstance == 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>
<!-- Check gl_InstanceID starts at 0 regardless of gl_BaseInstance --> <!-- Check gl_InstanceID starts at 0 regardless of gl_BaseInstance -->
<script id="vshaderInstanceIDCheck" type="x-shader/x-vertex">#version 300 es <script id="vshaderInstanceIDCheck" type="x-shader/x-vertex">#version 300 es
layout(location = 0) in vec2 vPosition; layout(location = 0) in vec2 vPosition;
@ -32,7 +46,7 @@ void main()
gl_Position = vec4(vPosition * 2.0 - 1.0, 0, 1); gl_Position = vec4(vPosition * 2.0 - 1.0, 0, 1);
} }
</script> </script>
<script id="vshaderBaseVertexWithoutExt" type="x-shader/x-vertex">#version 300 es <script id="vshaderIllegalBaseVertex" type="x-shader/x-vertex">#version 300 es
layout(location = 0) in vec2 vPosition; layout(location = 0) in vec2 vPosition;
out vec4 color; out vec4 color;
void main() void main()
@ -41,13 +55,17 @@ void main()
gl_Position = vec4(vPosition * 2.0 - 1.0, gl_BaseVertex, 1); gl_Position = vec4(vPosition * 2.0 - 1.0, gl_BaseVertex, 1);
} }
</script> </script>
<script id="vshaderWithExt" type="x-shader/x-vertex">#version 300 es <script id="vshaderBaseVertexZero" type="x-shader/x-vertex">#version 300 es
#extension GL_ANGLE_base_vertex_base_instance : require #extension GL_ANGLE_base_vertex_base_instance : require
layout(location = 0) in vec2 vPosition; layout(location = 0) in vec2 vPosition;
out vec4 color; out vec4 color;
void main() void main()
{ {
if (gl_BaseVertex == 0) {
color = vec4(0, 1, 0, 1); color = vec4(0, 1, 0, 1);
} else {
color = vec4(1, 0, 0, 1);
}
gl_Position = vec4(vPosition * 2.0 - 1.0, 0, 1); gl_Position = vec4(vPosition * 2.0 - 1.0, 0, 1);
} }
</script> </script>
@ -66,6 +84,7 @@ void main()
} }
</script> </script>
<script id="vshaderSimple" type="x-shader/x-vertex">#version 300 es <script id="vshaderSimple" type="x-shader/x-vertex">#version 300 es
#extension GL_ANGLE_base_vertex_base_instance : require
layout(location = 0) in vec2 vPosition; layout(location = 0) in vec2 vPosition;
layout(location = 1) in float vInstance; layout(location = 1) in float vInstance;
out vec4 color; out vec4 color;
@ -102,13 +121,7 @@ description("This test verifies the functionality of the WEBGL_[multi]_draw_base
const wtu = WebGLTestUtils; const wtu = WebGLTestUtils;
const canvas = document.getElementById("canvas"); const canvas = document.getElementById("canvas");
canvas.style.backgroundColor = '#000'; const gl = wtu.create3DContext(canvas, null, 2);
canvas.style.imageRendering = 'pixelated'; // Because Chrome doesn't support crisp-edges.
canvas.style.imageRendering = 'crisp-edges';
const attribs = {
antialias: false,
};
const gl = wtu.create3DContext(canvas, attribs, 2);
const width = gl.canvas.width; const width = gl.canvas.width;
const height = gl.canvas.height; const height = gl.canvas.height;
@ -120,7 +133,6 @@ const tileSize = [ 1/x_count, 1/y_count ];
const tilePixelSize = [ Math.floor(width / x_count), Math.floor(height / 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 quadRadius = [ 0.25 * tileSize[0], 0.25 * tileSize[1] ];
const pixelCheckSize = [ Math.floor(quadRadius[0] * width), Math.floor(quadRadius[1] * height) ]; const pixelCheckSize = [ Math.floor(quadRadius[0] * width), Math.floor(quadRadius[1] * height) ];
const bufferUsageSet = [ gl.STATIC_DRAW, gl.DYNAMIC_DRAW ];
function getTileCenter(x, y) { function getTileCenter(x, y) {
return [ tileSize[0] * (0.5 + x), tileSize[1] * (0.5 + y) ]; return [ tileSize[0] * (0.5 + x), tileSize[1] * (0.5 + y) ];
@ -181,6 +193,18 @@ const vertexBuffer = gl.createBuffer();
const nonIndexedVertexBuffer = gl.createBuffer(); const nonIndexedVertexBuffer = gl.createBuffer();
const instanceIDBuffer = gl.createBuffer(); const instanceIDBuffer = gl.createBuffer();
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, nonIndexedVertexBuffer);
gl.bufferData(gl.ARRAY_BUFFER, nonIndexedVertices, gl.STATIC_DRAW);
gl.bindBuffer(gl.ARRAY_BUFFER, instanceIDBuffer);
gl.bufferData(gl.ARRAY_BUFFER, instanceIDs, gl.STATIC_DRAW);
const drawArraysDrawCount = x_count / 2; const drawArraysDrawCount = x_count / 2;
let drawArraysParams = { let drawArraysParams = {
drawCount: drawArraysDrawCount, drawCount: drawArraysDrawCount,
@ -213,20 +237,6 @@ for (let v = 0; v < y_count; ++v) {
} }
} }
function setupGeneralBuffers(bufferUsage) {
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
gl.bufferData(gl.ARRAY_BUFFER, vertices, bufferUsage);
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indices, bufferUsage);
gl.bindBuffer(gl.ARRAY_BUFFER, nonIndexedVertexBuffer);
gl.bufferData(gl.ARRAY_BUFFER, nonIndexedVertices, bufferUsage);
gl.bindBuffer(gl.ARRAY_BUFFER, instanceIDBuffer);
gl.bufferData(gl.ARRAY_BUFFER, instanceIDs, bufferUsage);
}
// Check if the extension is either both enabled and supported or // Check if the extension is either both enabled and supported or
// not enabled and not supported. // not enabled and not supported.
function runSupportedTest(extensionName, extensionEnabled) { function runSupportedTest(extensionName, extensionEnabled) {
@ -257,245 +267,8 @@ function runTest() {
doTest('WEBGL_draw_instanced_base_vertex_base_instance', false); doTest('WEBGL_draw_instanced_base_vertex_base_instance', false);
doTest('WEBGL_multi_draw_instanced_base_vertex_base_instance', true); doTest('WEBGL_multi_draw_instanced_base_vertex_base_instance', true);
testGlslBuiltins();
} }
// -
function* range(n) {
for (let i = 0; i < n; i++) {
yield i;
}
}
function crossCombine(...args) {
function crossCombine2(listA, listB) {
const listC = [];
for (const a of listA) {
for (const b of listB) {
const c = Object.assign({}, a, b);
listC.push(c);
}
}
return listC;
}
let res = [{}];
while (args.length) {
const next = args.shift();
next[0].defined;
res = crossCombine2(res, next);
}
return res;
}
// -
const PASSTHROUGH_FRAG_SRC = `\
#version 300 es
precision mediump float;
in vec4 v_color;
out vec4 o_color;
void main() {
o_color = v_color;
}
`;
function testGlslBuiltins() {
const EXT = gl.getExtension('WEBGL_draw_instanced_base_vertex_base_instance');
const vertid_prog = (() => {
const vert_src = `\
#version 300 es
#line 405
layout(location = 0) in int a_vertex_id; // Same as first_vert+gl_VertexID
out vec4 v_color;
void main() {
gl_Position = vec4(0,0,0,1);
gl_PointSize = 1.0;
v_color = vec4(float(gl_VertexID), float(a_vertex_id),0,0);
v_color /= 255.0;
}
`;
const prog = wtu.setupProgram(gl, [vert_src, PASSTHROUGH_FRAG_SRC],
undefined, undefined, /*logShaders*/ true);
expectTrue(!!prog, `make_vertid_prog failed`);
return prog;
})();
const instid_prog = (() => {
const vert_src = `\
#version 300 es
#line 425
layout(location = 0) in int a_vertex_id; // Same as first_vert+gl_VertexID
layout(location = 1) in int a_instance_div1; // Same as base_instance+gl_InstanceID
layout(location = 2) in int a_instance_div2; // Same as base_instance+floor(gl_InstanceID/2)
layout(location = 3) in int a_instance_div3; // Same as base_instance+floor(gl_InstanceID/3)
out vec4 v_color;
void main() {
gl_Position = vec4(0,0,0,1);
gl_PointSize = 1.0;
v_color = vec4(float(gl_InstanceID), float(a_instance_div1),
float(a_instance_div2), float(a_instance_div3));
v_color /= 255.0;
}
`;
const prog = wtu.setupProgram(gl, [vert_src, PASSTHROUGH_FRAG_SRC],
undefined, undefined, /*logShaders*/ true);
expectTrue(!!prog, `make_instid_prog failed`);
return prog;
})();
const COUNT_UP_DATA = new Int32Array(1000);
for (const i in COUNT_UP_DATA) {
COUNT_UP_DATA[i] = i;
}
const vertex_id_buf = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vertex_id_buf);
gl.bufferData(gl.ARRAY_BUFFER, COUNT_UP_DATA, gl.STATIC_DRAW);
gl.enableVertexAttribArray(0);
gl.vertexAttribIPointer(0, 1, gl.INT, 0, 0);
gl.enableVertexAttribArray(1);
gl.vertexAttribIPointer(1, 1, gl.INT, 0, 0);
gl.vertexAttribDivisor(1, 1);
gl.enableVertexAttribArray(2);
gl.vertexAttribIPointer(2, 1, gl.INT, 0, 0);
gl.vertexAttribDivisor(2, 2);
gl.enableVertexAttribArray(3);
gl.vertexAttribIPointer(3, 1, gl.INT, 0, 0);
gl.vertexAttribDivisor(3, 3);
const index_buf = gl.createBuffer();
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, index_buf);
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, COUNT_UP_DATA, gl.STATIC_DRAW);
gl.canvas.width = gl.canvas.height = 1;
gl.canvas.style.width = gl.canvas.style.height = '1em';
gl.viewport(0, 0, 1, 1);
const expect_pixel = (() => {
const was = new Uint8Array(4);
return (desc, subtest, expected) => {
gl.readPixels(0, 0, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, was);
if (!areArraysEqual(was, expected)) {
testFailed(`${subtest}: Expected [${expected}], was [${was}]. desc: ${JSON.stringify(desc)}`);
} else {
debug(`${subtest}: Was [${was}] as expected.`);
}
};
})();
// Common setup complete
// -
// Create testcases
const DRAW_FUNC_COMBINER = [{
name: 'drawArraysInstanced',
draw: desc => {
if (desc.base_vert) return false;
if (desc.base_inst) return false;
gl.drawArraysInstanced(gl[desc.mode], desc.first_vert,
desc.vert_count, desc.inst_count);
return true;
},
}, {
name: 'drawElementsInstanced',
draw: desc => {
if (desc.base_vert) return false;
if (desc.base_inst) return false;
gl.drawElementsInstanced(gl[desc.mode], desc.vert_count,
gl.UNSIGNED_INT, 4*desc.first_vert, desc.inst_count);
return true;
},
}, {
name: 'drawArraysInstancedBaseInstanceWEBGL',
draw: desc => {
if (desc.base_vert) return false;
if (!EXT) return false;
EXT.drawArraysInstancedBaseInstanceWEBGL(gl[desc.mode],
desc.first_vert, desc.vert_count, desc.inst_count,
desc.base_inst);
return true;
},
}, {
name: 'drawElementsInstancedBaseVertexBaseInstanceWEBGL',
draw: desc => {
if (!EXT) return false;
EXT.drawElementsInstancedBaseVertexBaseInstanceWEBGL(
gl[desc.mode], desc.vert_count, gl.UNSIGNED_INT, 4*desc.first_vert,
desc.inst_count, desc.base_vert, desc.base_inst);
return true;
},
}];
// -
function make_key_combiner(key, vals) {
const ret = [];
for (const v of vals) {
const cur = {};
cur[key] = v;
ret.push(cur);
}
return ret;
}
const TEST_DESCS = crossCombine(
DRAW_FUNC_COMBINER,
make_key_combiner('base_vert', [0,1,2]),
make_key_combiner('vert_count', [0,1,2]),
make_key_combiner('base_inst', [0,1,2]),
make_key_combiner('inst_count', range(10)),
make_key_combiner('first_vert', [0,1,2]),
);
console.log('TEST_DESCS', TEST_DESCS);
// -
// Run testcases
gl.disable(gl.DEPTH_TEST);
gl.disable(gl.STENCIL_TEST);
gl.disable(gl.BLEND);
for (const desc of TEST_DESCS) {
gl.disable(gl.SCISSOR_TEST);
gl.clearBufferfv(gl.COLOR, 0, [1,0,0,1]);
const last_gl_vert_id = desc.base_vert + desc.vert_count - 1;
const last_vert_id = desc.first_vert + last_gl_vert_id;
const last_inst_id = desc.inst_count - 1;
const last_inst_div1 = desc.base_inst + last_inst_id;
const last_inst_div2 = desc.base_inst + Math.floor(last_inst_id / 2);
const last_inst_div3 = desc.base_inst + Math.floor(last_inst_id / 3);
gl.useProgram(vertid_prog);
if (!desc.draw(desc)) continue;
debug('\ndesc: ' + JSON.stringify(desc));
wtu.glErrorAssert(gl, 0);
if (!desc.vert_count || !desc.inst_count) {
expect_pixel(desc, 'vertid_prog', [255, 0, 0, 255]);
continue;
}
expect_pixel(desc, 'vertid_prog', [last_gl_vert_id, last_vert_id, 0, 0]);
gl.useProgram(instid_prog);
desc.draw(desc);
expect_pixel(desc, 'instid_prog', [last_inst_id, last_inst_div1, last_inst_div2, last_inst_div3]);
}
}
// -
function doTest(extensionName, multiDraw) { function doTest(extensionName, multiDraw) {
const ext = gl.getExtension(extensionName); const ext = gl.getExtension(extensionName);
if (!runSupportedTest(extensionName, ext)) { if (!runSupportedTest(extensionName, ext)) {
@ -506,20 +279,21 @@ function doTest(extensionName, multiDraw) {
const vs = [ const vs = [
'#version 300 es', '#version 300 es',
config.isMultiDraw ? '#extension GL_ANGLE_multi_draw : require' : '', config.isMultiDraw ? '#extension GL_ANGLE_multi_draw : require' : '',
//'#extension GL_ANGLE_base_vertex_base_instance : require', '#extension GL_ANGLE_base_vertex_base_instance : require',
'#define kCountX ' + countX.toString(), '#define kCountX ' + countX.toString(),
'#define kCountY ' + countY.toString(), '#define kCountY ' + countY.toString(),
'layout(location = 0) in vec2 vPosition;', 'layout(location = 0) in vec2 vPosition;',
'layout(location = 1) in float vInstanceID;', config.useBaseInstanceBuiltin ? '' : 'layout(location = 1) in float vInstanceID;',
'out vec4 color;', 'out vec4 color;',
'void main()', 'void main()',
'{', '{',
' const float xStep = 1.0 / float(kCountX);', ' const float xStep = 1.0 / float(kCountX);',
' const float yStep = 1.0 / float(kCountY);', ' const float yStep = 1.0 / float(kCountY);',
' float xID = vInstanceID;', ' float xID = ' + (config.useBaseInstanceBuiltin ? 'float(gl_InstanceID + gl_BaseInstance)' : 'vInstanceID') + ';',
' float xColor = 1.0 - xStep * xID;', ' float xColor = 1.0 - xStep * xID;',
' float yID = floor(float(gl_VertexID) / ' + (config.isDrawArrays ? '6.0' : '4.0') + ' + 0.01);', ' float yID = floor(float(gl_VertexID) / ' + (config.isDrawArrays ? '6.0' : '4.0') + ' + 0.01);',
' color = vec4(xColor, 1.0 - yStep * yID, 1.0', ' color = vec4(xColor, 1.0 - yStep * yID, ',
config.useBaseVertexBuiltin ? '1.0 - yStep * float(gl_BaseVertex) / 4.0' : '1.0',
' , 1.0);', ' , 1.0);',
' mat3 transform = mat3(1.0);', ' mat3 transform = mat3(1.0);',
' transform[2][0] = xID * xStep;', ' transform[2][0] = xID * xStep;',
@ -532,20 +306,20 @@ function doTest(extensionName, multiDraw) {
return [vs, fs]; return [vs, fs];
} }
function runValidationTests(bufferUsage) { function runValidationTests() {
const vertexBuffer = gl.createBuffer(); const vertexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer); 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 ]), bufferUsage); 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(); const indexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer); gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint8Array([ 0, 1, 2 ]), bufferUsage); gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint8Array([ 0, 1, 2 ]), gl.STATIC_DRAW);
const instanceBuffer = gl.createBuffer(); const instanceBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, instanceBuffer); gl.bindBuffer(gl.ARRAY_BUFFER, instanceBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([ 0, 1, 2 ]), bufferUsage); gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([ 0, 1, 2 ]), gl.STATIC_DRAW);
const program = wtu.setupProgram(gl, ['vshaderSimple', 'fshader'], ['vPosition, vInstanceID'], [0, 1], true); const program = wtu.setupProgram(gl, ['vshaderSimple', 'fshader'], ['vPosition, vInstanceID'], [0, 1]);
expectTrue(program != null, "can compile simple program"); expectTrue(program != null, "can compile simple program");
function setupInstanced() { function setupInstanced() {
@ -712,28 +486,39 @@ function doTest(extensionName, multiDraw) {
} }
} }
function runShaderTests(bufferUsage) { function runShaderTests() {
let badProgram; const illegalBaseInstanceProgram = wtu.setupProgram(gl, ["vshaderIllegalBaseInstance", "fshader"]);
expectTrue(illegalBaseInstanceProgram == null, "cannot compile program with gl_BaseInstance but no extension directive");
badProgram = wtu.setupProgram(gl, ["vshaderBaseInstanceWithoutExt", "fshader"]); const illegalBaseVertexProgram = wtu.setupProgram(gl, ["vshaderIllegalBaseVertex", "fshader"]);
expectTrue(!badProgram, "cannot compile program with gl_BaseInstance but no extension directive"); expectTrue(illegalBaseVertexProgram == null, "cannot compile program with gl_BaseVertex but no extension directive");
badProgram = wtu.setupProgram(gl, ["vshaderBaseVertexWithoutExt", "fshader"]);
expectTrue(!badProgram, "cannot compile program with gl_BaseVertex but no extension directive");
badProgram = wtu.setupProgram(gl, ["vshaderWithExt", "fshader"]);
expectTrue(!badProgram, "cannot compile program with #extension GL_ANGLE_base_vertex_base_instance");
const x = Math.floor(width * 0.4); const x = Math.floor(width * 0.4);
const y = Math.floor(height * 0.4); const y = Math.floor(height * 0.4);
const xSize = Math.floor(width * 0.2); const xSize = Math.floor(width * 0.2);
const ySize = Math.floor(height * 0.2); const ySize = Math.floor(height * 0.2);
// gl_InstanceID // gl_BaseInstance and gl_InstanceID
gl.bindBuffer(gl.ARRAY_BUFFER, gl.createBuffer()); gl.bindBuffer(gl.ARRAY_BUFFER, gl.createBuffer());
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([ 0,0, 1,0, 0.5,1, 0,1, 0.5,0, 1,1 ]), bufferUsage); gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([ 0,0, 1,0, 0.5,1, 0,1, 0.5,0, 1,1 ]), gl.STATIC_DRAW);
gl.enableVertexAttribArray(0); gl.enableVertexAttribArray(0);
gl.vertexAttribPointer(0, 2, gl.FLOAT, false, 0, 0); gl.vertexAttribPointer(0, 2, gl.FLOAT, false, 0, 0);
const baseInstanceZeroProgram = wtu.setupProgram(gl, ["vshaderBaseInstanceZero", "fshader"], ["vPosition"], [0]);
expectTrue(baseInstanceZeroProgram !== null, "can compile program with gl_BaseInstance");
gl.useProgram(baseInstanceZeroProgram);
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
if (!multiDraw) {
ext.drawArraysInstancedBaseInstanceWEBGL(gl.TRIANGLES, 0, 6, 1, 5);
} else {
ext.multiDrawArraysInstancedBaseInstanceWEBGL(gl.TRIANGLES, [0], 0, [6], 0, [1], 0, [5], 0, 1);
}
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
gl.drawArrays(gl.TRIANGLES, 0, 6);
wtu.checkCanvasRect(gl, x, y, xSize, ySize, [0, 255, 0, 255], "gl_BaseInstance is 0 for non-BaseInstance draw calls");
const instanceIDProgram = wtu.setupProgram(gl, ["vshaderInstanceIDCheck", "fshader"], ["vPosition"], [0]); const instanceIDProgram = wtu.setupProgram(gl, ["vshaderInstanceIDCheck", "fshader"], ["vPosition"], [0]);
expectTrue(instanceIDProgram !== null, "can compile program with gl_InstanceID"); expectTrue(instanceIDProgram !== null, "can compile program with gl_InstanceID");
gl.useProgram(instanceIDProgram); gl.useProgram(instanceIDProgram);
@ -747,14 +532,30 @@ function doTest(extensionName, multiDraw) {
wtu.checkCanvasRect(gl, x, y, xSize, ySize, [0, 255, 0, 255], "gl_InstanceID should always starts from 0"); wtu.checkCanvasRect(gl, x, y, xSize, ySize, [0, 255, 0, 255], "gl_InstanceID should always starts from 0");
// gl_VertexID // gl_BaseVertex and gl_VertexID
gl.bindBuffer(gl.ARRAY_BUFFER, gl.createBuffer()); gl.bindBuffer(gl.ARRAY_BUFFER, gl.createBuffer());
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([ 0,0, 1,0, 0.5,1, 0,1, 0.5,0, 1,1, 0,0, 1,0, 0.5,1, 0,1 ]), bufferUsage); gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([ 0,0, 1,0, 0.5,1, 0,1, 0.5,0, 1,1, 0,0, 1,0, 0.5,1, 0,1 ]), gl.STATIC_DRAW);
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, gl.createBuffer()); gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, gl.createBuffer());
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint8Array([0, 1, 2, 3, 4, 5]), bufferUsage); gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint8Array([0, 1, 2, 3, 4, 5]), gl.STATIC_DRAW);
gl.enableVertexAttribArray(0); gl.enableVertexAttribArray(0);
gl.vertexAttribPointer(0, 2, gl.FLOAT, false, 0, 0); gl.vertexAttribPointer(0, 2, gl.FLOAT, false, 0, 0);
const baseVertexZeroProgram = wtu.setupProgram(gl, ["vshaderBaseVertexZero", "fshader"], ["vPosition"], [0]);
expectTrue(baseVertexZeroProgram !== null, "can compile program with gl_BaseVertex");
gl.useProgram(baseVertexZeroProgram);
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
if (!multiDraw) {
ext.drawElementsInstancedBaseVertexBaseInstanceWEBGL(gl.TRIANGLES, 6, gl.UNSIGNED_BYTE, 0, 1, 3, 0);
} else {
ext.multiDrawElementsInstancedBaseVertexBaseInstanceWEBGL(gl.TRIANGLES, [6], 0, gl.UNSIGNED_BYTE, [0], 0, [1], 0, [3], 0, [0], 0, 1);
}
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_BYTE, 0);
wtu.checkCanvasRect(gl, x, y, xSize, ySize, [0, 255, 0, 255], "gl_BaseVertex is 0 for non-BaseVertex draw calls");
const vertexIDProgram = wtu.setupProgram(gl, ["vshaderVertexIDCheck", "fshader"], ["vPosition"], [0]); const vertexIDProgram = wtu.setupProgram(gl, ["vshaderVertexIDCheck", "fshader"], ["vPosition"], [0]);
expectTrue(vertexIDProgram !== null, "can compile program with gl_VertexID"); expectTrue(vertexIDProgram !== null, "can compile program with gl_VertexID");
gl.useProgram(vertexIDProgram); gl.useProgram(vertexIDProgram);
@ -873,6 +674,30 @@ function doTest(extensionName, multiDraw) {
useBaseInstanceBuiltin: false useBaseInstanceBuiltin: false
}); });
checkDraw({
drawFunc: multiDraw ? multiDrawArraysInstancedBaseInstance : drawArraysInstancedBaseInstance,
isDrawArrays: true,
isMultiDraw: multiDraw,
useBaseVertexBuiltin: true,
useBaseInstanceBuiltin: false
});
checkDraw({
drawFunc: multiDraw ? multiDrawArraysInstancedBaseInstance : drawArraysInstancedBaseInstance,
isDrawArrays: true,
isMultiDraw: multiDraw,
useBaseVertexBuiltin: false,
useBaseInstanceBuiltin: true
});
checkDraw({
drawFunc: multiDraw ? multiDrawArraysInstancedBaseInstance : drawArraysInstancedBaseInstance,
isDrawArrays: true,
isMultiDraw: multiDraw,
useBaseVertexBuiltin: true,
useBaseInstanceBuiltin: true
});
checkDraw({ checkDraw({
drawFunc: multiDraw ? multiDrawElementsInstancedBaseVertexBaseInstance : drawElementsInstancedBaseVertexBaseInstance, drawFunc: multiDraw ? multiDrawElementsInstancedBaseVertexBaseInstance : drawElementsInstancedBaseVertexBaseInstance,
isDrawArrays: false, isDrawArrays: false,
@ -880,16 +705,35 @@ function doTest(extensionName, multiDraw) {
useBaseVertexBuiltin: false, useBaseVertexBuiltin: false,
useBaseInstanceBuiltin: false useBaseInstanceBuiltin: false
}); });
checkDraw({
drawFunc: multiDraw ? multiDrawElementsInstancedBaseVertexBaseInstance : drawElementsInstancedBaseVertexBaseInstance,
isDrawArrays: false,
isMultiDraw: multiDraw,
useBaseVertexBuiltin: true,
useBaseInstanceBuiltin: false
});
checkDraw({
drawFunc: multiDraw ? multiDrawElementsInstancedBaseVertexBaseInstance : drawElementsInstancedBaseVertexBaseInstance,
isDrawArrays: false,
isMultiDraw: multiDraw,
useBaseVertexBuiltin: false,
useBaseInstanceBuiltin: true
});
checkDraw({
drawFunc: multiDraw ? multiDrawElementsInstancedBaseVertexBaseInstance : drawElementsInstancedBaseVertexBaseInstance,
isDrawArrays: false,
isMultiDraw: multiDraw,
useBaseVertexBuiltin: true,
useBaseInstanceBuiltin: true
});
} }
for (let i = 0; i < bufferUsageSet.length; i++) { runValidationTests();
let bufferUsage = bufferUsageSet[i]; runShaderTests();
debug("Testing with BufferUsage = " + bufferUsage);
setupGeneralBuffers(bufferUsage);
runValidationTests(bufferUsage);
runShaderTests(bufferUsage);
runPixelTests(); runPixelTests();
}
} }
runTest(); runTest();

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

@ -17,7 +17,6 @@ const-array-init.html
forbidden-operators.html forbidden-operators.html
--min-version 2.0.1 forward-declaration.html --min-version 2.0.1 forward-declaration.html
frag-depth.html frag-depth.html
--min-version 2.0.1 fragment-shader-loop-crash.html
--min-version 2.0.1 gradient-in-discontinuous-loop.html --min-version 2.0.1 gradient-in-discontinuous-loop.html
--min-version 2.0.1 input-with-interpotaion-as-lvalue.html --min-version 2.0.1 input-with-interpotaion-as-lvalue.html
invalid-default-precision.html invalid-default-precision.html
@ -27,8 +26,6 @@ loops-with-side-effects.html
--min-version 2.0.1 matrix-row-major-dynamic-indexing.html --min-version 2.0.1 matrix-row-major-dynamic-indexing.html
misplaced-version-directive.html misplaced-version-directive.html
--min-version 2.0.1 no-attribute-vertex-shader.html --min-version 2.0.1 no-attribute-vertex-shader.html
--min-version 2.0.1 precision-side-effects-bug.html
--min-version 2.0.1 reciprocal-sqrt-of-sum-of-squares-crash.html
sampler-no-precision.html sampler-no-precision.html
--min-version 2.0.1 sampler-array-indexing.html --min-version 2.0.1 sampler-array-indexing.html
sequence-operator-returns-non-constant.html sequence-operator-returns-non-constant.html
@ -45,7 +42,6 @@ short-circuiting-in-loop-condition.html
texture-offset-out-of-range.html texture-offset-out-of-range.html
--min-version 2.0.1 texture-offset-uniform-texture-coordinate.html --min-version 2.0.1 texture-offset-uniform-texture-coordinate.html
--min-version 2.0.1 tricky-loop-conditions.html --min-version 2.0.1 tricky-loop-conditions.html
--min-version 2.0.1 uint-int-shift-bug.html
--min-version 2.0.1 unary-minus-operator-in-dynamic-loop.html --min-version 2.0.1 unary-minus-operator-in-dynamic-loop.html
uniform-block-layouts.html uniform-block-layouts.html
uniform-block-layout-match.html uniform-block-layout-match.html

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

@ -1,72 +0,0 @@
<!--
Copyright (c) 2021 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">
<title>Fragment shader containing loop should not crash</title>
<link rel="stylesheet" href="../../resources/js-test-style.css"/>
<link rel="stylesheet" href="../../resources/glsl-feature-tests.css"/>
<script src="../../js/js-test-pre.js"></script>
<script src="../../js/webgl-test-utils.js"></script>
<script src="../../js/glsl-conformance-test.js"></script>
</head>
<body>
<div id="description"></div>
<div id="console"></div>
<script id="vshader" type="x-shader/x-vertex">#version 300 es
precision highp float;
out vec2 v_tex_coord;
uniform mat4 matrix;
void main() {
v_tex_coord = vec2(0.0, 0.0);
gl_Position = vec4(0.0, 0.0, 0.0, 0.0);
}
</script>
<script id="fshader" type="x-shader/x-fragment">#version 300 es
precision highp float;
in vec2 v_tex_coord;
out vec4 out_color;
uniform sampler2D texture_1;
uniform vec2 resolution;
vec4 do_loops(vec4 z)
{
vec4 v[16];
for (int i = 0; i < 16; i++)
{
v[i] = z;
}
return v[1];
}
void main() {
out_color = do_loops(vec4(0.2, 0.4, 0.6, 1.0)) - texture(texture_1, v_tex_coord);
}
</script>
<script type="application/javascript">
"use strict";
description();
const wtu = WebGLTestUtils;
const tests = [
{
vShaderSource: wtu.getScript('vshader'),
fShaderSource: wtu.getScript('fshader'),
vShaderSuccess: true,
fShaderSuccess: true,
linkSuccess: true,
passMsg: 'Fragment shader containing a simple loop should compile and link'
}
];
GLSLConformanceTester.runTests(tests, 2);
</script>
</body>
</html>

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

@ -1,125 +0,0 @@
<!--
Copyright (c) 2020 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">
<title>Verify precision side effects (Adreno driver bug)</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="canvas" width="2" height="2"> </canvas>
<div id="description"></div>
<div id="console"></div>
<script id="vshader-simple" type="x-shader/x-vertex">#version 300 es
in vec3 aPosition;
void main() {
gl_Position = vec4(aPosition, 1.0);
}
</script>
<script id="fshader-int" type="x-shader/x-fragment">#version 300 es
out highp vec4 myFragColor;
void main() {
highp int t;
t = 0 | (int(t == t) * 0x8000);
if (t == 0x8000)
myFragColor = vec4(1.0, 0.0, 0.0, 1.0);
else
myFragColor = vec4(0.0, 0.0, 0.0, 1.0);
}
</script>
<script id="fshader-ivec2" type="x-shader/x-fragment">#version 300 es
out highp vec4 myFragColor;
void main() {
highp ivec2 t;
t = 0 | (ivec2(t == t) * 0x8000);
if (t == ivec2(0x8000))
myFragColor = vec4(1.0, 0.0, 0.0, 1.0);
else
myFragColor = vec4(0.0, 0.0, 0.0, 1.0);
}
</script>
<script id="fshader-ivec3" type="x-shader/x-fragment">#version 300 es
out highp vec4 myFragColor;
void main() {
highp ivec3 t;
t = 0 | (ivec3(t == t) * 0x8000);
if (t == ivec3(0x8000))
myFragColor = vec4(1.0, 0.0, 0.0, 1.0);
else
myFragColor = vec4(0.0, 0.0, 0.0, 1.0);
}
</script>
<script id="fshader-ivec4" type="x-shader/x-fragment">#version 300 es
out highp vec4 myFragColor;
void main() {
highp ivec4 t;
t = 0 | (ivec4(t == t) * 0x8000);
if (t == ivec4(0x8000))
myFragColor = vec4(1.0, 0.0, 0.0, 1.0);
else
myFragColor = vec4(0.0, 0.0, 0.0, 1.0);
}
</script>
<script type="application/javascript">
"use strict";
description("Verify precision side effects");
debug("");
debug("When this test is run on Adreno (no repros on other vendors so far):");
debug(" - the result of the expression 0 | (int(e0 == e0) * 0x8000) somehow returns -32768 instead of 32768 despite the variable using highp precision;");
debug(" - splitting the expression along | fixes the issue (could also be observed with other operators).");
debug('For additional reference see this <a href="https://github.com/KhronosGroup/WebGL/pull/3192">pull request</a> and <a href="http://crbug.com/1155942">Chromium bug</a>');
debug("");
var wtu = WebGLTestUtils;
function test() {
var gl = wtu.create3DContext("canvas", undefined, 2);
if (!gl) {
testFailed("context does not exist");
return;
}
wtu.setupUnitQuad(gl);
var testCases = [
{ vshader: "vshader-simple", fshader: "fshader-int", desc: "fragment shader int" },
{ vshader: "vshader-simple", fshader: "fshader-ivec2", desc: "fragment shader ivec2" },
{ vshader: "vshader-simple", fshader: "fshader-ivec3", desc: "fragment shader ivec3" },
{ vshader: "vshader-simple", fshader: "fshader-ivec4", desc: "fragment shader ivec4" },
];
for (var idx = 0; idx < testCases.length; ++idx) {
var test = testCases[idx];
debug("");
var program = wtu.setupProgram(gl, [test.vshader, test.fshader], ["aPosition"]);
if (!program) {
testFailed("Fail to set up program");
} else {
debug("Testing " + test.desc);
wtu.drawUnitQuad(gl);
wtu.checkCanvas(gl, [255, 0, 0, 255]);
gl.deleteProgram(program);
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors from testing");
}
}
};
test();
debug("");
var successfullyParsed = true;
</script>
<script src="../../js/js-test-post.js"></script>
</body>
</html>

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

@ -1,66 +0,0 @@
<!--
Copyright (c) 2021 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">
<title>Shader identified as containing reciprocal square root of sum of squares should not crash</title>
<link rel="stylesheet" href="../../resources/js-test-style.css"/>
<link rel="stylesheet" href="../../resources/glsl-feature-tests.css"/>
<script src="../../js/js-test-pre.js"></script>
<script src="../../js/webgl-test-utils.js"></script>
<script src="../../js/glsl-conformance-test.js"></script>
</head>
<body>
<div id="description"></div>
<div id="console"></div>
<script id="vshader" type="x-shader/x-vertex">#version 300 es
void main() {
gl_Position = vec4(0.0, 0.0, 0.0, 0.0);
}
</script>
<script id="fshader" type="x-shader/x-fragment">#version 300 es
precision highp float;
#define CRASH 1
out vec4 fragmentColor;
void main()
{
vec2 p = gl_FragCoord.xy;
// This expression meets the requirement of being the reciprocal
// square root of a sum of squares.
float d = 1.0 / length(p);
#if CRASH
if (p.x > 0.0)
{
d *= 2.0;
}
#endif
fragmentColor = vec4(d);
}
</script>
<script type="application/javascript">
"use strict";
description();
debug('Regression test for <a href="https://crbug.com/1079309">crbug.com/1079309</a>');
const wtu = WebGLTestUtils;
const tests = [
{
vShaderSource: wtu.getScript('vshader'),
fShaderSource: wtu.getScript('fshader'),
vShaderSuccess: true,
fShaderSuccess: true,
linkSuccess: true,
passMsg: 'Shader containing expression that driver recognizes as reciprocal square root of sum of squares should compile and link'
}
];
GLSLConformanceTester.runTests(tests, 2);
</script>
</body>
</html>

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

@ -36,59 +36,6 @@ void main()
} }
} }
</script> </script>
<script id="fshaderDeclarationInsideSwitchDefault" type="x-shader/x-fragment">#version 300 es
precision highp float;
out vec4 my_FragColor;
uniform int u_zero;
void main()
{
my_FragColor = vec4(1, 0, 0, 1);
switch (u_zero)
{
default:
ivec2 i;
i = ivec2(1, 0);
my_FragColor = vec4(0, i[0], 0, 1);
}
}
</script>
<script id="fshaderDeclarationInsideSwitchLiteral" type="x-shader/x-fragment">#version 300 es
precision highp float;
out vec4 my_FragColor;
void main()
{
my_FragColor = vec4(1, 0, 0, 1);
switch (0)
{
case 0:
ivec2 i;
i = ivec2(1, 0);
my_FragColor = vec4(0, i[0], 0, 1);
}
}
</script>
<script id="fshaderDeclarationInsideSwitchLiteralDefault" type="x-shader/x-fragment">#version 300 es
precision highp float;
out vec4 my_FragColor;
void main()
{
my_FragColor = vec4(1, 0, 0, 1);
switch (0)
{
default:
ivec2 i;
i = ivec2(1, 0);
my_FragColor = vec4(0, i[0], 0, 1);
}
}
</script>
<script id="fshaderDeclarationInsideSwitchScope" type="x-shader/x-fragment">#version 300 es <script id="fshaderDeclarationInsideSwitchScope" type="x-shader/x-fragment">#version 300 es
precision highp float; precision highp float;
@ -274,27 +221,6 @@ GLSLConformanceTester.runTests([
passMsg: 'Declaration inside switch should work.', passMsg: 'Declaration inside switch should work.',
render: true render: true
}, },
{
fShaderId: 'fshaderDeclarationInsideSwitchDefault',
fShaderSuccess: true,
linkSuccess: true,
passMsg: 'Declaration inside switch default case should work.',
render: true
},
{
fShaderId: 'fshaderDeclarationInsideSwitchLiteral',
fShaderSuccess: true,
linkSuccess: true,
passMsg: 'Declaration inside switch with literal value should work.',
render: true
},
{
fShaderId: 'fshaderDeclarationInsideSwitchLiteralDefault',
fShaderSuccess: true,
linkSuccess: true,
passMsg: 'Declaration inside switch with literal value and default case should work.',
render: true
},
{ {
fShaderId: 'fshaderDeclarationInsideSwitchScope', fShaderId: 'fshaderDeclarationInsideSwitchScope',
fShaderSuccess: true, fShaderSuccess: true,

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

@ -1,106 +0,0 @@
<!--
Copyright (c) 2020 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">
<title>Verify (uint(int) >> 31) works correctly (Adreno driver bug)</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="canvas" width="2" height="2"> </canvas>
<div id="description"></div>
<div id="console"></div>
<script id="vshader-uint-1" type="x-shader/x-vertex">#version 300 es
in vec3 aPosition;
flat out highp uint uvalue;
uniform highp int ivalue;
void main() {
gl_Position = vec4(aPosition, 1);
uvalue = uint(ivalue) >> 31u;
}
</script>
<script id="fshader-uint-1" type="x-shader/x-fragment">#version 300 es
flat in highp uint uvalue;
out highp vec4 myFragColor;
void main() {
if (uvalue == 1u)
myFragColor = vec4(1.0, 0.0, 0.0, 1.0);
else
myFragColor = vec4(0.0, 0.0, 0.0, 1.0);
}
</script>
<script id="vshader-simple" type="x-shader/x-vertex">#version 300 es
in vec3 aPosition;
void main() {
gl_Position = vec4(aPosition, 1);
}
</script>
<script id="fshader-uint-2" type="x-shader/x-fragment">#version 300 es
uniform highp int ivalue;
out highp vec4 myFragColor;
void main() {
uint uvalue = uint(ivalue) >> 31u;
if (uvalue == 1u)
myFragColor = vec4(1.0, 0.0, 0.0, 1.0);
else
myFragColor = vec4(0.0, 0.0, 0.0, 1.0);
}
</script>
<script type="application/javascript">
"use strict";
description("Verify (uint(int) >> 31) works correctly");
debug("");
var wtu = WebGLTestUtils;
function test() {
var gl = wtu.create3DContext("canvas", undefined, 2);
if (!gl) {
testFailed("context does not exist");
return;
}
wtu.setupUnitQuad(gl);
var testCases = [
{ vshader: "vshader-uint-1", fshader: "fshader-uint-1", desc: "vertex shader uint" },
{ vshader: "vshader-simple", fshader: "fshader-uint-2", desc: "fragment shader uint" },
];
for (var idx = 0; idx < testCases.length; ++idx) {
var test = testCases[idx];
debug("");
var program = wtu.setupProgram(gl, [test.vshader, test.fshader], ["aPosition"]);
if (!program) {
testFailed("Fail to set up program");
} else {
var uniformLoc = gl.getUniformLocation(program, 'ivalue');
gl.uniform1i(uniformLoc, -1);
wtu.drawUnitQuad(gl);
wtu.checkCanvas(gl, [255, 0, 0, 255]);
gl.deleteProgram(program);
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors from testing");
}
}
};
test();
debug("");
var successfullyParsed = true;
</script>
<script src="../../js/js-test-post.js"></script>
</body>
</html>

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

@ -1,7 +1,6 @@
expando-loss-2.html expando-loss-2.html
getextension-while-pbo-bound-stability.html getextension-while-pbo-bound-stability.html
instanceof-test.html instanceof-test.html
--min-version 2.0.1 null-object-behaviour-2.html
object-deletion-behaviour-2.html object-deletion-behaviour-2.html
uninitialized-test-2.html uninitialized-test-2.html
views-with-offsets.html views-with-offsets.html

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

@ -1,61 +0,0 @@
<!--
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>
</head>
<body>
<div id="description"></div>
<div id="console"></div>
<script>
"use strict";
var wtu = WebGLTestUtils;
description("Tests calling WebGL 2 APIs without providing the necessary objects");
var gl = wtu.create3DContext(undefined, undefined, 2);
var shouldGenerateGLError = wtu.shouldGenerateGLError;
for (let nullOrUndefined of [null, undefined]) {
shouldGenerateGLError(gl, gl.NO_ERROR, `gl.deleteQuery(${nullOrUndefined})`);
shouldGenerateGLError(gl, gl.NO_ERROR, `gl.isQuery(${nullOrUndefined})`);
shouldGenerateGLError(gl, gl.NO_ERROR, `gl.deleteSync(${nullOrUndefined})`);
shouldGenerateGLError(gl, gl.NO_ERROR, `gl.isSync(${nullOrUndefined})`);
shouldGenerateGLError(gl, gl.NO_ERROR, `gl.deleteTransformFeedback(${nullOrUndefined})`);
shouldGenerateGLError(gl, gl.NO_ERROR, `gl.isTransformFeedback(${nullOrUndefined})`);
shouldGenerateGLError(gl, gl.NO_ERROR, `gl.deleteSampler(${nullOrUndefined})`);
shouldGenerateGLError(gl, gl.NO_ERROR, `gl.isSampler(${nullOrUndefined})`);
shouldGenerateGLError(gl, gl.NO_ERROR, `gl.deleteVertexArray(${nullOrUndefined})`);
shouldGenerateGLError(gl, gl.NO_ERROR, `gl.isVertexArray(${nullOrUndefined})`);
shouldGenerateGLError(gl, gl.NO_ERROR, `gl.bindSampler(0, ${nullOrUndefined})`);
shouldThrow(`gl.samplerParameteri(${nullOrUndefined}, gl.TEXTURE_MAG_FILTER, gl.NEAREST)`);
shouldThrow(`gl.samplerParameterf(${nullOrUndefined}, gl.TEXTURE_MAX_LOD, 1)`);
shouldThrow(`gl.getSamplerParameter(${nullOrUndefined}, gl.TEXTURE_MAX_LOD)`);
shouldThrow(`gl.waitSync(${nullOrUndefined}, 0, 0)`);
shouldThrow(`gl.clientWaitSync(${nullOrUndefined}, 0, 0)`);
shouldThrow(`gl.getSyncParameter(${nullOrUndefined}, gl.OBJECT_TYPE)`);
shouldGenerateGLError(gl, gl.NO_ERROR, `gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, ${nullOrUndefined})`);
shouldThrow(`gl.transformFeedbackVaryings(${nullOrUndefined}, [], gl.SEPARATE_ATTRIBS)`);
shouldGenerateGLError(gl, gl.NO_ERROR, `gl.bindVertexArray(${nullOrUndefined})`);
}
var successfullyParsed = true;
</script>
<script src="../../js/js-test-post.js"></script>
</body>
</html>

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

@ -122,16 +122,6 @@ function runCurrentQueryTest() {
gl.beginQuery(gl.TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, q1); gl.beginQuery(gl.TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, q1);
wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "beginning a deleted query object"); wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "beginning a deleted query object");
shouldBeNull("gl.getQuery(gl.TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, gl.CURRENT_QUERY)"); shouldBeNull("gl.getQuery(gl.TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, gl.CURRENT_QUERY)");
debug("");
debug("Firefox bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1636525");
q1 = gl.createQuery();
gl.deleteQuery(q1);
wtu.glErrorShouldBe(gl, 0, "DeleteQuery after CreateQuery");
gl.beginQuery(gl.TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, q1);
wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "Begining a deleted query");
shouldBeNull("gl.getQuery(gl.TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, gl.CURRENT_QUERY)");
} }
function runObjectTest() { function runObjectTest() {

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

@ -322,7 +322,6 @@ function testPackParameters(usePixelPackBuffer)
runTestIteration(0, 0, 2, 3, {alignment:8, skipPixels:2}, usePixelPackBuffer, false); runTestIteration(0, 0, 2, 3, {alignment:8, skipPixels:2}, usePixelPackBuffer, false);
runTestIteration(0, 0, 2, 3, {alignment:8, skipPixels:1, skipRows:3}, usePixelPackBuffer, false); runTestIteration(0, 0, 2, 3, {alignment:8, skipPixels:1, skipRows:3}, usePixelPackBuffer, false);
runTestIteration(0, 0, 2, 3, {alignment:8, skipRows:3}, usePixelPackBuffer, true); runTestIteration(0, 0, 2, 3, {alignment:8, skipRows:3}, usePixelPackBuffer, true);
runTestIteration(0, 0, 2, 3, {skipPixels:1, rowLength:4}, usePixelPackBuffer, true);
} }
debug(""); debug("");

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

@ -412,29 +412,6 @@ testFramebufferWithImagesOfDifferentSizes();
testUsingIncompleteFramebuffer(); testUsingIncompleteFramebuffer();
testReadingFromMissingAttachment(); testReadingFromMissingAttachment();
// -
debug("");
debug("Test calling framebufferTexture2D with impossible mip levels.");
const fb = gl.createFramebuffer();
gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
const tex = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, tex);
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex, 1000);
wtu.glErrorShouldBe(gl, gl.INVALID_VALUE, "Mip level attachment impossibly high.");
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex, 10);
wtu.glErrorShouldBe(gl, 0, "Mip level attachment within acceptable range.");
// Firefox bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1636517 :
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, null, 1000);
wtu.glErrorShouldBe(gl, 0, "Mip level detachment can be impossibly high.");
shouldBe("gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE)", "0");
// -
debug("") debug("")
var successfullyParsed = true; var successfullyParsed = true;
</script> </script>

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

@ -78,8 +78,8 @@ var testReadBufferOnFBO = function() {
var maxColorAttachments = gl.getParameter(gl.MAX_COLOR_ATTACHMENTS); var maxColorAttachments = gl.getParameter(gl.MAX_COLOR_ATTACHMENTS);
gl.readBuffer(gl.COLOR_ATTACHMENT0 + maxColorAttachments); gl.readBuffer(gl.COLOR_ATTACHMENT0 + maxColorAttachments);
wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, wtu.glErrorShouldBe(gl, gl.INVALID_ENUM,
"calling readBuffer with GL_COLOR_ATTACHMENTi that exceeds MAX_COLOR_ATTACHMENT on fbo should generate INVALID_OPERATION."); "calling readBuffer with GL_COLOR_ATTACHMENTi that exceeds MAX_COLOR_ATTACHMENT on fbo should generate INVALID_ENUM.");
gl.readBuffer(gl.COLOR_ATTACHMENT1); gl.readBuffer(gl.COLOR_ATTACHMENT1);
wtu.glErrorShouldBe(gl, gl.NO_ERROR, wtu.glErrorShouldBe(gl, gl.NO_ERROR,
"calling readBuffer with GL_COLOR_ATTACHMENT1 on the fbo should succeed."); "calling readBuffer with GL_COLOR_ATTACHMENT1 on the fbo should succeed.");

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

@ -20,12 +20,10 @@ clear-func-buffer-type-match.html
draw-buffers.html draw-buffers.html
--min-version 2.0.1 draw-buffers-dirty-state-bug.html --min-version 2.0.1 draw-buffers-dirty-state-bug.html
--min-version 2.0.1 draw-buffers-driver-hang.html --min-version 2.0.1 draw-buffers-driver-hang.html
--min-version 2.0.1 draw-buffers-sparse-output-locations.html
--min-version 2.0.1 draw-with-integer-texture-base-level.html --min-version 2.0.1 draw-with-integer-texture-base-level.html
element-index-uint.html element-index-uint.html
--min-version 2.0.1 framebuffer-completeness-draw-framebuffer.html --min-version 2.0.1 framebuffer-completeness-draw-framebuffer.html
framebuffer-completeness-unaffected.html framebuffer-completeness-unaffected.html
--min-version 2.0.1 framebuffer-mismatched-attachment-targets.html
--min-version 2.0.1 framebuffer-render-to-layer.html --min-version 2.0.1 framebuffer-render-to-layer.html
--min-version 2.0.1 framebuffer-render-to-layer-angle-issue.html --min-version 2.0.1 framebuffer-render-to-layer-angle-issue.html
--min-version 2.0.1 framebuffer-texture-changing-base-level.html --min-version 2.0.1 framebuffer-texture-changing-base-level.html
@ -38,7 +36,6 @@ instanced-arrays.html
--min-version 2.0.1 line-rendering-quality.html --min-version 2.0.1 line-rendering-quality.html
--min-version 2.0.1 multisampling-fragment-evaluation.html --min-version 2.0.1 multisampling-fragment-evaluation.html
out-of-bounds-index-buffers-after-copying.html out-of-bounds-index-buffers-after-copying.html
--min-version 2.0.1 rasterizer-discard-and-implicit-clear.html
--min-version 2.0.1 read-draw-when-missing-image.html --min-version 2.0.1 read-draw-when-missing-image.html
rgb-format-support.html rgb-format-support.html
uniform-block-buffer-size.html uniform-block-buffer-size.html

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

@ -72,51 +72,57 @@ function blitframebuffer_filter_outofbounds(readbufferFormat, drawbufferFormat,
if (gl.checkFramebufferStatus(gl.READ_FRAMEBUFFER) == gl.FRAMEBUFFER_COMPLETE) { if (gl.checkFramebufferStatus(gl.READ_FRAMEBUFFER) == gl.FRAMEBUFFER_COMPLETE) {
// Blit read framebuffer to the image in draw framebuffer. // Blit read framebuffer to the image in draw framebuffer.
var tests = [ var test = [
// [srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1] // [srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1]
[-2, -2, 4, 4, 1, 1, 4, 4], // only src region is out-of-bounds, dst region has different width/height as src region.
{ args: [-2, -2, 4, 4, 1, 1, 4, 4], changedDstRect: [2, 2, 4, 4], desc: 'only src region is out-of-bounds, dst region has different width/height as src region.'}, [-2, -2, 4, 4, 1, 1, 7, 7], // only src region is out-of-bounds, dst region has the same width/height as src region.
{ args: [-2, -2, 4, 4, 1, 1, 7, 7], changedDstRect: [3, 3, 7, 7], desc: 'only src region is out-of-bounds, dst region has the same width/height as src region.'}, [0, 0, 6, 6, 7, 7, 10, 10], // only dst region is out-of-bounds, dst region has different width/height as src region after dst region is clipped to the bounds of draw buffer.
{ args: [0, 0, 6, 6, 7, 7, 10, 10], changedDstRect: [7, 7, 8, 8], desc: 'only dst region is out-of-bounds, dst region has different width/height as src region after dst region is clipped to the bounds of draw buffer.'}, [0, 0, 6, 6, 4, 4, 10, 10], // only dst region is out-of-bounds, dst region has the same width/height as src region after dst region is clipped to the bounds of draw buffer.
{ args: [0, 0, 6, 6, 4, 4, 10, 10], changedDstRect: [4, 4, 8, 8], desc: 'only dst region is out-of-bounds, dst region has the same width/height as src region after dst region is clipped to the bounds of draw buffer.'}, [-2, -2, 4, 4, 7, 7, 10, 10], // both src and dst region are out-of-bounds, dst region has different width/height as src region after dst region is clipped to the bounds of draw buffer.
{ args: [-2, -2, 4, 4, 7, 7, 10, 10], changedDstRect: [8, 8, 8, 8], desc: 'both src and dst region are out-of-bounds, dst region has different width/height as src region after dst region is clipped to the bounds of draw buffer.'}, [-2, -2, 4, 4, 4, 4, 10, 10], // both src and dst region are out-of-bounds, dst region has the same width/height as src region after dst region is clipped to the bounds of draw buffer.
{ args: [-2, -2, 4, 4, 4, 4, 10, 10], changedDstRect: [6, 6, 8, 8], desc: 'both src and dst region are out-of-bounds, dst region has the same width/height as src region after dst region is clipped to the bounds of draw buffer.'}, [-2, -2, 4, 4, 2, 2, 10, 10], // both src and dst region are out-of-bounds. There are some dst pixels (x and y are within [4, 8] , and x or y equals to 4) whose corresponding src pixels are partially inside and partially outside the real sampling area of the src region (the real sampling area is [0, 0, 4, 4]). But the centers of such src pixels are lying outside the real sampling area.
{ args: [-2, -2, 4, 4, 2, 2, 10, 10], changedDstRect: [2 + 2/6*8, 2 + 2/6*8, 8, 8], desc: 'both src and dst region are out-of-bounds. There are some dst pixels (x and y are within [4, 8] , and x or y equals to 4) whose corresponding src pixels are partially inside and partially outside the real sampling area of the src region (the real sampling area is [0, 0, 4, 4]). But the centers of such src pixels are lying outside the real sampling area.'}, [-2, -2, 4, 4, 3, 3, 10, 10], // both src and dst region are out-of-bounds. There are some dst pixels (x and y are within [4, 7] , and x or y equals to 5) whose corresponding src pixels are partially inside and partially outside the real sampling area of the src region (the real sampling area is [0, 0, 4, 4]). But the centers of such src pixels are lying inside the real sampling area.
{ args: [-2, -2, 4, 4, 3, 3, 10, 10], changedDstRect: [5, 5, 8, 8], desc: 'both src and dst region are out-of-bounds. There are some dst pixels (x and y are within [4, 7] , and x or y equals to 5) whose corresponding src pixels are partially inside and partially outside the real sampling area of the src region (the real sampling area is [0, 0, 4, 4]). But the centers of such src pixels are lying inside the real sampling area.'}, [-2, -2, 4, 4, 10, 10, 2, 2], // both src and dst region are out-of-bounds, and the dst coordinates are reversed. There are some dst pixels (x and y are within [2, 7] , and x or y equals to 7) whose corresponding src pixels are partially inside and partially outside the real sampling area of the src region (the real sampling area is [0, 0, 4, 4]). But the centers of such src pixels are lying outside the real sampling area.
{ args: [-2, -2, 4, 4, 10, 10, 2, 2], changedDstRect: [2, 2, 7, 7], desc: 'both src and dst region are out-of-bounds, and the dst coordinates are reversed. There are some dst pixels (x and y are within [2, 7] , and x or y equals to 7) whose corresponding src pixels are partially inside and partially outside the real sampling area of the src region (the real sampling area is [0, 0, 4, 4]). But the centers of such src pixels are lying outside the real sampling area.'}, [-2, -2, 4, 4, 10, 10, 3, 3], // both src and dst region are out-of-bounds, and the dst coordinates are reversed. There are some dst pixels (x and y are within [3, 7] , and x or y equals to 7) whose corresponding src pixels are partially inside and partially outside the read sampling area of the src region (the real sampling area is [0, 0, 4, 4]). But the centers of such src pixels are lying inside the real sampling area.
{ args: [-2, -2, 4, 4, 10, 10, 3, 3], changedDstRect: [3, 3, 8, 8], desc: 'both src and dst region are out-of-bounds, and the dst coordinates are reversed. There are some dst pixels (x and y are within [3, 7] , and x or y equals to 7) whose corresponding src pixels are partially inside and partially outside the read sampling area of the src region (the real sampling area is [0, 0, 4, 4]). But the centers of such src pixels are lying inside the real sampling area.'},
]; ];
var realBlittedDstRegion = [
[2, 2, 4, 4],
[3, 3, 7, 7],
[7, 7, 8, 8],
[4, 4, 8, 8],
[8, 8, 8, 8],
[6, 6, 8, 8],
[5, 5, 8, 8],
[5, 5, 8, 8],
[2, 2, 7, 7],
[3, 3, 8, 8],
]
var readbufferHasSRGBImage = (readbufferFormat == gl.SRGB8_ALPHA8); var readbufferHasSRGBImage = (readbufferFormat == gl.SRGB8_ALPHA8);
var drawbufferHasSRGBImage = (drawbufferFormat == gl.SRGB8_ALPHA8); var drawbufferHasSRGBImage = (drawbufferFormat == gl.SRGB8_ALPHA8);
for (const test of tests) { for (var i = 0; i < test.length; ++i) {
const args = test.args;
const changedDstRect = test.changedDstRect;
debug(""); debug("");
debug("Both the read framebuffer and draw framebuffer bounds are [0, 0, 8, 8]"); debug("both the read framebuffer and draw framebuffer bounds are [0, 0, 8, 8]");
debug(`Blitting from src region [${args.slice(0, 4)}] to dst region [${args.slice(4, 8)}]`); debug("blitting from src region [" + test[i][0] + ", " + test[i][1] + ", " + test[i][2] + ", " + test[i][3] + "] to dst region [" + test[i][4] + ", " + test[i][5] + ", " + test[i][6] + ", " + test[i][7] + "]");
debug(`Expects changed dst region of [${changedDstRect}]`);
debug(`Explaination: ${test.desc}`);
gl.bindFramebuffer(gl.READ_FRAMEBUFFER, fbo_read); gl.bindFramebuffer(gl.READ_FRAMEBUFFER, fbo_read);
gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, fbo_draw); gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, fbo_draw);
gl.bindTexture(gl.TEXTURE_2D, tex_draw); gl.bindTexture(gl.TEXTURE_2D, tex_draw);
gl.texImage2D(gl.TEXTURE_2D, 0, drawbufferFormat, size, size, 0, gl.RGBA, gl.UNSIGNED_BYTE, null); gl.texImage2D(gl.TEXTURE_2D, 0, drawbufferFormat, size, size, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
gl.blitFramebuffer(args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7], gl.COLOR_BUFFER_BIT, filter); gl.blitFramebuffer(test[i][0], test[i][1], test[i][2], test[i][3], test[i][4], test[i][5], test[i][6], test[i][7], gl.COLOR_BUFFER_BIT, filter);
// Read pixels and check the correctness. // Read pixels and check the correctness.
var pixels = new Uint8Array(size * size * 4); var pixels = new Uint8Array(size * size * 4);
gl.bindFramebuffer(gl.READ_FRAMEBUFFER, fbo_draw); gl.bindFramebuffer(gl.READ_FRAMEBUFFER, fbo_draw);
gl.readPixels(0, 0, size, size, gl.RGBA, gl.UNSIGNED_BYTE, pixels); gl.readPixels(0, 0, size, size, gl.RGBA, gl.UNSIGNED_BYTE, pixels);
for (var ii = 0; ii < size; ++ii) { for (var ii = 0; ii < size; ++ii) {
for (var jj = 0; jj < size; ++jj) { for (var jj = 0; jj < size; ++jj) {
var loc = ii * size + jj; var loc = ii * size + jj;
var color = [pixels[loc * 4], pixels[loc * 4 + 1], pixels[loc * 4 + 2], pixels[loc * 4 + 3]]; var color = [pixels[loc * 4], pixels[loc * 4 + 1], pixels[loc * 4 + 2], pixels[loc * 4 + 3]];
var expectedColor = [0, 0, 0, 0]; var expectedColor = [0, 0, 0, 0];
if (ii >= changedDstRect[0] && ii < changedDstRect[2] && jj >= changedDstRect[1] && jj < changedDstRect[3]) { if (ii >= realBlittedDstRegion[i][0] && ii < realBlittedDstRegion[i][2] && jj >= realBlittedDstRegion[i][1] && jj < realBlittedDstRegion[i][3]) {
expectedColor = [0x20, 0x20, 0x20, 0xff]; expectedColor = [0x20, 0x20, 0x20, 0xff];
// We may need to covert the color space for pixels in blit region // We may need to covert the color space for pixels in blit region
@ -157,7 +163,6 @@ if (!gl) {
var filters = [gl.LINEAR, gl.NEAREST]; var filters = [gl.LINEAR, gl.NEAREST];
for (var ii = 0; ii < filters.length; ++ii) { for (var ii = 0; ii < filters.length; ++ii) {
blitframebuffer_filter_outofbounds(gl.RGBA8, gl.RGBA8, filters[ii]); blitframebuffer_filter_outofbounds(gl.RGBA8, gl.RGBA8, filters[ii]);
break;
blitframebuffer_filter_outofbounds(gl.RGBA8, gl.SRGB8_ALPHA8, filters[ii]); blitframebuffer_filter_outofbounds(gl.RGBA8, gl.SRGB8_ALPHA8, filters[ii]);
blitframebuffer_filter_outofbounds(gl.SRGB8_ALPHA8, gl.RGBA8, filters[ii]); blitframebuffer_filter_outofbounds(gl.SRGB8_ALPHA8, gl.RGBA8, filters[ii]);
blitframebuffer_filter_outofbounds(gl.SRGB8_ALPHA8, gl.SRGB8_ALPHA8, filters[ii]); blitframebuffer_filter_outofbounds(gl.SRGB8_ALPHA8, gl.SRGB8_ALPHA8, filters[ii]);

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

@ -71,7 +71,7 @@ function clear_srgb_color_buffer(iter) {
} }
var color_ref = wtu.linearToSRGB(color); var color_ref = wtu.linearToSRGB(color);
var tolerance = 3; var tolerance = 1;
var msg = ""; var msg = "";
wtu.checkCanvasRect(gl, 0, 0, size, size, color_ref, msg, tolerance); wtu.checkCanvasRect(gl, 0, 0, size, size, color_ref, msg, tolerance);
} }

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

@ -1,108 +0,0 @@
<!--
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">
<title>WebGL Conformance Tests: Verify drawBuffers sparse output locations</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" width="1" height="1" style="width: 4px; height: 4px;"> </canvas>
<div id="console"></div>
<script id="vs" type="x-shader/x-vertex">#version 300 es
void main() {
gl_PointSize = 100.0;
gl_Position = vec4(0, 0, 0, 1);
}
</script>
<script id="fs" type="x-shader/x-fragment">#version 300 es
// fragment shader only outputs to attachments 1 and 3
precision highp float;
layout(location = 1) out vec4 output1;
layout(location = 3) out vec4 output2;
void main()
{
output1 = vec4(0.0, 1.0, 0.0, 1.0);
output2 = vec4(0.0, 0.0, 1.0, 1.0);
}
</script>
<script>
"use strict";
description("This test verifies sparse output locations of fragment shaders render correctly");
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");
runTests();
}
function testAttachment(attachment, expected) {
gl.readBuffer(gl.COLOR_ATTACHMENT0 + attachment);
wtu.checkCanvas(gl, expected, `check COLOR_ATTACHMENT${attachment}`, 1);
}
function runTests() {
var program = wtu.setupProgram(gl, ["vs", "fs"]);
if (!program) {
testFailed("Set up program failed");
return;
}
gl.useProgram(program);
// create a framebuffer with 4 1x1 pixel color attachments
const fb = gl.createFramebuffer();
gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
for (let i = 0; i < 4; ++i) {
const tex = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, tex);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA8, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0 + i, gl.TEXTURE_2D, tex, 0);
}
// draw only to the 1st and 3rd attachments
gl.drawBuffers([
gl.NONE,
gl.COLOR_ATTACHMENT1,
gl.NONE,
gl.COLOR_ATTACHMENT3,
]);
// draw
gl.drawArrays(gl.POINTS, 0, 1);
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "No GL error from set up");
// check we got the correct values
testAttachment(0, [0, 0, 0, 0]);
testAttachment(1, [0, 255, 0, 255]);
testAttachment(2, [0, 0, 0, 0]);
testAttachment(3, [0, 0, 255, 255]);
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "No GL error from testing");
}
var successfullyParsed = true;
</script>
<script src="../../js/js-test-post.js"></script>
</body>
</html>

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

@ -1,162 +0,0 @@
<!--
Copyright (c) 2020 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">
<title>WebGL2 can render to framebuffer attachments with different targets</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 id="vshader" type="x-shader/x-vertex">#version 300 es
void main(void) {
gl_Position = vec4(-0.5, -0.5, 0, 1);
gl_PointSize = 1.0;
}
</script>
<script id="fshader" type="x-shader/x-fragment">#version 300 es
precision mediump float;
out vec4 outColor;
void main() {
outColor = vec4(0, 1, 0, 1);
}
</script>
</head>
<body>
<canvas id="example" width="1", height="1"></canvas>
<div id="description"></div>
<div id="console"></div>
<script>
"use strict";
debug("");
description("Test framebuffer attachments with different targets");
const wtu = WebGLTestUtils;
const gl = wtu.create3DContext("example", undefined, 2);
if (!gl) {
testFailed("WebGL context creation failed");
} else {
testPassed("WebGL context creation succeeded");
runTest();
}
function newResource(target, mipLevels, format, size) {
let ret;
switch (target) {
case gl.RENDERBUFFER: {
ret = gl.createRenderbuffer();
ret.mips = [ ret ];
for (let i = 1; i < mipLevels; i++) {
ret.mips.push(gl.createRenderbuffer());
}
for (const i in ret.mips) {
const rb = ret.mips[i];
gl.bindRenderbuffer(target, rb);
gl.renderbufferStorage(target, format, size>>i, size>>i);
}
ret.attach = (attachEnum, mipLevel) => {
const rb = ret.mips[mipLevel];
gl.framebufferRenderbuffer(gl.FRAMEBUFFER, attachEnum, gl.RENDERBUFFER, rb);
};
break;
}
case gl.TEXTURE_2D:
case gl.TEXTURE_CUBE_MAP: {
ret = gl.createTexture();
gl.bindTexture(target, ret);
gl.texStorage2D(target, mipLevels, format, size, size);
let imageTarget = target;
if (imageTarget == gl.TEXTURE_CUBE_MAP) {
imageTarget = gl.TEXTURE_CUBE_MAP_POSITIVE_X+2; // Deliberately don't choose the first image.
}
ret.attach = (attachEnum, mipLevel) => {
gl.framebufferTexture2D(gl.FRAMEBUFFER, attachEnum, imageTarget, ret, mipLevel);
};
break;
}
case gl.TEXTURE_3D:
case gl.TEXTURE_2D_ARRAY: {
ret = gl.createTexture();
gl.bindTexture(target, ret);
gl.texStorage3D(target, mipLevels, format, size, size, 1);
ret.attach = (attachEnum, mipLevel) => {
gl.framebufferTextureLayer(gl.FRAMEBUFFER, attachEnum, ret, mipLevel, 0);
};
break;
}
default:
throw new Error();
}
ret.target = wtu.glEnumToString(gl, target);
ret.format = wtu.glEnumToString(gl, format);
return ret;
}
function runTest() {
const MIP_LEVELS = 2;
const SIZE = 2;
gl.clearColor(1, 0, 0, 1);
const program = wtu.setupProgram(gl, ['vshader','fshader'], [], console.log.bind(console));
gl.useProgram(program);
const colorResList = [
newResource(gl.RENDERBUFFER, MIP_LEVELS, gl.RGBA8, SIZE),
newResource(gl.TEXTURE_2D, MIP_LEVELS, gl.RGBA8, SIZE),
newResource(gl.TEXTURE_CUBE_MAP, MIP_LEVELS, gl.RGBA8, SIZE),
newResource(gl.TEXTURE_3D, MIP_LEVELS, gl.RGBA8, SIZE),
newResource(gl.TEXTURE_2D_ARRAY, MIP_LEVELS, gl.RGBA8, SIZE),
];
const depthResList = [
newResource(gl.RENDERBUFFER, MIP_LEVELS, gl.DEPTH_COMPONENT16, SIZE),
newResource(gl.TEXTURE_2D, MIP_LEVELS, gl.DEPTH_COMPONENT16, SIZE),
newResource(gl.TEXTURE_CUBE_MAP, MIP_LEVELS, gl.DEPTH_COMPONENT16, SIZE),
//newResource(gl.TEXTURE_3D, MIP_LEVELS, gl.DEPTH_COMPONENT16, SIZE), // Depth formats forbidden for TEXTURE_3D.
newResource(gl.TEXTURE_2D_ARRAY, MIP_LEVELS, gl.DEPTH_COMPONENT16, SIZE),
];
const fb = gl.createFramebuffer();
gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
for (const color of colorResList) {
for (const depth of depthResList) {
debug(`\ncolor: ${color.target}; depth: ${depth.target}`);
for (let mipLevel = 0; mipLevel < MIP_LEVELS; mipLevel++) {
debug(`mipLevel: ${mipLevel}`);
color.attach(gl.COLOR_ATTACHMENT0, mipLevel);
depth.attach(gl.DEPTH_ATTACHMENT, mipLevel);
const maybeStatus = wtu.framebufferStatusShouldBe(gl, gl.FRAMEBUFFER, [gl.FRAMEBUFFER_COMPLETE, gl.FRAMEBUFFER_UNSUPPORTED]);
if (!maybeStatus || maybeStatus[0] != gl.FRAMEBUFFER_COMPLETE) {
continue;
}
gl.clear(gl.COLOR_BUFFER_BIT);
wtu.checkCanvas(gl, [255, 0, 0, 255], `framebuffer layer ${mipLevel} should be cleared red`);
gl.drawArrays(gl.POINTS, 0, 1);
wtu.checkCanvas(gl, [0, 255, 0, 255], `framebuffer layer ${mipLevel} should be drawn green`);
wtu.glErrorShouldBe(gl, gl.NO_ERROR, `No errors`);
}
}
}
// make sure we were not rendering to the canvas.
gl.bindFramebuffer(gl.FRAMEBUFFER, null)
wtu.checkCanvas(gl, [0, 0, 0, 0], "canvas should be zero");
}
debug("");
var successfullyParsed = true;
</script>
<script src="../../js/js-test-post.js"></script>
</body>
</html>

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

@ -123,9 +123,6 @@ function runOutputTests() {
0.0, 1.0, 0.0, 1.0, // Green 0.0, 1.0, 0.0, 1.0, // Green
0.0, 0.0, 1.0, 1.0, // Blue 0.0, 0.0, 1.0, 1.0, // Blue
1.0, 1.0, 0.0, 1.0, // Yellow 1.0, 1.0, 0.0, 1.0, // Yellow
// extra data when colorLoc divisor is set back to 0
1.0, 1.0, 0.0, 1.0, // Yellow
1.0, 1.0, 0.0, 1.0, // Yellow
]); ]);
var colorBuffer = gl.createBuffer(); var colorBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer); gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer);
@ -177,45 +174,6 @@ function runOutputTests() {
gl.drawArraysInstanced(desktopGL['POLYGON'], 0, 6, instanceCount); gl.drawArraysInstanced(desktopGL['POLYGON'], 0, 6, instanceCount);
wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, "drawArraysInstanced with POLYGON should return INVALID_ENUM"); wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, "drawArraysInstanced with POLYGON should return INVALID_ENUM");
debug("Testing drawArraysInstanced with param 'first' > 0");
gl.clear(gl.COLOR_BUFFER_BIT);
wtu.setupQuad(gl, {
positionLocation: 0,
scale: 0.5
});
var offsetsHalf = new Float32Array([
-0.5, 0.5,
0.5, 0.5,
-0.5, -0.5,
0.5, -0.5
]);
gl.bindBuffer(gl.ARRAY_BUFFER, offsetBuffer);
gl.bufferData(gl.ARRAY_BUFFER, offsetsHalf, gl.STATIC_DRAW);
gl.drawArraysInstanced(gl.TRIANGLES, 3, 3, instanceCount);
var w = Math.floor(0.25*canvas.width),
h = Math.floor(0.25*canvas.height);
wtu.checkCanvasRect(gl, Math.ceil(0.25*canvas.width), 0.5*canvas.height, w, h, [255, 0, 0, 255]);
wtu.checkCanvasRect(gl, Math.ceil(0.75*canvas.width), 0.5*canvas.height, w, h, [0, 255, 0, 255]);
wtu.checkCanvasRect(gl, Math.ceil(0.25*canvas.width), 0, w, h, [0, 0, 255, 255]);
wtu.checkCanvasRect(gl, Math.ceil(0.75*canvas.width), 0, w, h, [255, 255, 0, 255]);
debug("Testing drawArraysInstanced with attributes 'divisor' reset to 0");
debug("Correct rendering output: 4 yellow triangles");
debug("Possible incorrect rendering output: missing triangles, or triangles with different color at each vertex");
gl.vertexAttribDivisor(colorLoc, 0);
gl.clear(gl.COLOR_BUFFER_BIT);
gl.drawArraysInstanced(gl.TRIANGLES, 3, 3, instanceCount);
wtu.checkCanvasRect(gl, Math.ceil(0.25*canvas.width), 0.5*canvas.height, w, h, [255, 255, 0, 255]);
wtu.checkCanvasRect(gl, Math.ceil(0.75*canvas.width), 0.5*canvas.height, w, h, [255, 255, 0, 255]);
wtu.checkCanvasRect(gl, Math.ceil(0.25*canvas.width), 0, w, h, [255, 255, 0, 255]);
wtu.checkCanvasRect(gl, Math.ceil(0.75*canvas.width), 0, w, h, [255, 255, 0, 255]);
gl.vertexAttribDivisor(colorLoc, 1);
wtu.setupUnitQuad(gl, 0);
gl.bindBuffer(gl.ARRAY_BUFFER, offsetBuffer);
gl.bufferData(gl.ARRAY_BUFFER, offsets, gl.STATIC_DRAW);
// Draw 2: Draw indexed instances // Draw 2: Draw indexed instances
debug("Testing drawElementsInstanced"); debug("Testing drawElementsInstanced");
gl.clear(gl.COLOR_BUFFER_BIT); gl.clear(gl.COLOR_BUFFER_BIT);

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

@ -1,149 +0,0 @@
<!--
Copyright (c) 2020 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">
<title>RASTERIZER_DISCARD doesn't affect 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 id="vshader" type="x-shader/x-vertex">#version 300 es
layout(location=0) in vec2 vPosition;
uniform float xTranslation;
void main(void) {
gl_Position = vec4(vPosition[0] + xTranslation, vPosition[1], 0.0, 1.0);
}
</script>
<script id="fshader" type="x-shader/x-fragment">#version 300 es
precision mediump float;
uniform vec4 color;
out vec4 outColor;
void main() {
outColor = color;
}
</script>
</head>
<body>
<canvas id="example"></canvas>
<div id="description"></div>
<div id="console"></div>
<script>
"use strict";
debug("");
description("Enabling RASTERIZER_DISCARD should not affect implicit clears");
const wtu = WebGLTestUtils;
const canvas = document.getElementById("example");
const sz = canvas.width = canvas.height = 256;
const gl = wtu.create3DContext(canvas, undefined, 2);
const NUM_FRAMES = 15;
let framesToGo = NUM_FRAMES;
let xTranslationLoc;
let colorLoc;
const positionLocation = 0;
const red = [ 1.0, 0.0, 0.0, 1.0 ];
const green = [ 0.0, 1.0, 0.0, 1.0 ];
const transparentBlackRender = [ 0, 0, 0, 0 ];
const greenRender = [ 0, 255, 0, 255 ];
if (!gl) {
testFailed("WebGL context creation failed");
finishTest();
} else {
testPassed("WebGL context creation succeeded");
runDrawTest();
}
function runDrawTest() {
debug("Verify that draws with rasterizer discard enabled do not interfere with implicit clears");
let prog = wtu.loadProgramFromScript(gl, "vshader", "fshader");
gl.useProgram(prog);
xTranslationLoc = gl.getUniformLocation(prog, "xTranslation");
colorLoc = gl.getUniformLocation(prog, "color");
let leftRectBuffer = gl.createBuffer();
gl.enableVertexAttribArray(positionLocation);
gl.bindBuffer(gl.ARRAY_BUFFER, leftRectBuffer);
// Create a rectangle covering the left half of the viewport, in
// normalized device coordinates.
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
0.0, 1.0,
-1.0, 1.0,
-1.0, -1.0,
0.0, 1.0,
-1.0, -1.0,
0.0, -1.0]), gl.STATIC_DRAW);
gl.vertexAttribPointer(positionLocation, 2, gl.FLOAT, false, 0, 0);
requestAnimationFrame(renderDrawTestFrame);
}
function renderDrawTestFrame() {
// Animation is required in order to expose this bug. When it
// occurs, the rectangle leaves trails behind it.
gl.uniform1f(xTranslationLoc, 0.0);
gl.enable(gl.RASTERIZER_DISCARD);
gl.uniform4fv(colorLoc, red);
gl.drawArrays(gl.TRIANGLES, 0, 6);
gl.disable(gl.RASTERIZER_DISCARD);
// Animate the rectangle from the left to the right half of the viewport.
gl.uniform1f(xTranslationLoc, (NUM_FRAMES - framesToGo) / NUM_FRAMES);
// Draw the last frame with green so any (incorrect) trails are visibly red.
if (framesToGo == 0)
gl.uniform4fv(colorLoc, green);
gl.drawArrays(gl.TRIANGLES, 0, 6);
if (framesToGo-- == 0) {
// The left half of the canvas should be transparent black,
// which comes from the implicit clear just before drawing the
// rectangle without rasterizer discard enabled.
wtu.checkCanvasRect(gl, 0, 0, sz / 2, sz, transparentBlackRender, "left half of canvas should be clear", 3);
// The right half of the canvas should be solid green, from
// the last render of the translated rectangle.
wtu.checkCanvasRect(gl, sz / 2, 0, sz / 2, sz, greenRender, "right half of canvas should be green", 3);
runReadPixelsTest();
} else {
requestAnimationFrame(renderDrawTestFrame);
}
}
function runReadPixelsTest() {
debug("Verify that readPixels with rasterizer discard enabled receives implicitly cleared data");
framesToGo = NUM_FRAMES; // Reset state.
// Clear to transparent black.
gl.clearColor(0.0, 0.0, 0.0, 0.0);
gl.clear(gl.COLOR_BUFFER_BIT);
// Start with rasterizer discard enabled.
gl.enable(gl.RASTERIZER_DISCARD);
requestAnimationFrame(renderReadPixelsTestFrame);
}
function renderReadPixelsTestFrame() {
// Rasterizer discard is enabled at the beginning of this test.
// The canvas should always contain transparent black at the beginning of the frame.
wtu.checkCanvasRect(gl, 0, 0, sz, sz, transparentBlackRender, undefined, 3);
gl.disable(gl.RASTERIZER_DISCARD);
// Clear to red.
gl.clearColor(1.0, 0.0, 0.0, 1.0);
gl.clear(gl.COLOR_BUFFER_BIT);
// Enable rasterizer discard again.
gl.enable(gl.RASTERIZER_DISCARD);
if (--framesToGo == 0) {
finishTest();
} else {
requestAnimationFrame(renderReadPixelsTestFrame);
}
}
</script>
</body>
</html>

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

@ -2,7 +2,6 @@
--min-version 2.0.1 angle-stuck-depth-textures.html --min-version 2.0.1 angle-stuck-depth-textures.html
canvas-remains-unchanged-after-used-in-webgl-texture.html canvas-remains-unchanged-after-used-in-webgl-texture.html
--min-version 2.0.1 compressed-tex-from-pbo-crash.html --min-version 2.0.1 compressed-tex-from-pbo-crash.html
--min-version 2.0.1 compressed-tex-image.html
--min-version 2.0.1 copy-texture-cube-map-AMD-bug.html --min-version 2.0.1 copy-texture-cube-map-AMD-bug.html
--min-version 2.0.1 copy-texture-cube-map-bug.html --min-version 2.0.1 copy-texture-cube-map-bug.html
copy-texture-image.html copy-texture-image.html
@ -11,7 +10,6 @@ copy-texture-image-luma-format.html
copy-texture-image-webgl-specific.html copy-texture-image-webgl-specific.html
--min-version 2.0.1 generate-mipmap-with-large-base-level.html --min-version 2.0.1 generate-mipmap-with-large-base-level.html
gl-get-tex-parameter.html gl-get-tex-parameter.html
--min-version 2.0.1 immutable-tex-render-feedback.html
--min-version 2.0.1 integer-cubemap-texture-sampling.html --min-version 2.0.1 integer-cubemap-texture-sampling.html
--min-version 2.0.1 integer-cubemap-specification-order-bug.html --min-version 2.0.1 integer-cubemap-specification-order-bug.html
mipmap-fbo.html mipmap-fbo.html

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

@ -1,24 +0,0 @@
<!--
Copyright (c) 2020 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>
</head>
<body>
<div id="description"></div>
<div id="console"></div>
<script>
const contextVersion = 2;
</script>
<script src="../../../js/tests/compressed-tex-image.js"></script>
<script src="../../../js/js-test-post.js"></script>
</body>
</html>

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

@ -1,221 +0,0 @@
<!--
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">
<title>Ensure sampling-feedback detection can allow certain immutable texture uses</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="console"></div>
<script>
"use strict";
const wtu = WebGLTestUtils;
description();
const gl = wtu.create3DContext(undefined, undefined, 2);
function* range(a, b) {
a.required;
if (b === undefined) {
b = a;
a = 0;
}
for (let i = a; i < b; i += 1) {
yield i;
}
}
const VS = `\
void main() {
gl_PointSize = 1.0;
}
`;
const FS = `\
uniform sampler2D u_tex0;
void main() {
gl_FragColor = texture2D(u_tex0, vec2(0));
}
`;
const prog = wtu.loadProgram(gl, VS, FS);
gl.useProgram(prog);
(() => {
const MIPS = 3;
const SIZE = 10;
const immutTex = gl.createTexture();
immutTex.name = "immutTex";
immutTex.immutable = true;
gl.bindTexture(gl.TEXTURE_2D, immutTex);
gl.texStorage2D(gl.TEXTURE_2D, MIPS, gl.RGBA8, SIZE, SIZE);
const mutTex = gl.createTexture();
mutTex.name = "mutTex";
mutTex.immutable = false;
gl.bindTexture(gl.TEXTURE_2D, mutTex);
for (const mip of range(MIPS)) {
const size = SIZE >> mip;
gl.texImage2D(gl.TEXTURE_2D, mip, gl.RGBA8, size, size, 0,
gl.RGBA, gl.UNSIGNED_BYTE, null);
}
const MAG_FILTERS = [
'LINEAR',
'NEAREST',
];
const MIN_FILTERS = [
['LINEAR',false],
['LINEAR_MIPMAP_LINEAR',true],
['LINEAR_MIPMAP_NEAREST',true],
['NEAREST',false],
['NEAREST_MIPMAP_LINEAR',true],
['NEAREST_MIPMAP_NEAREST',true],
];
const fb = gl.createFramebuffer();
gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
debug(`
mips: ${MIPS}: [0,${MIPS-1}] (inclusive)
size: ${SIZE}`);
const texs = [
immutTex,
mutTex,
];
for (const tex of texs) {
debug(`\
immutable: ${tex.immutable}`);
gl.bindTexture(gl.TEXTURE_2D, tex);
for (const level_prime_base of range(MIPS+1)) { // `level_base` in GLES
// ES 3.0.6 p150
let _level_base = level_prime_base;
if (tex.immutable) {
_level_base = Math.min(_level_base, MIPS-1);
}
const level_base = _level_base;
for (let _level_prime_max of range(level_prime_base-1, MIPS+2)) { // `q` in GLES
if (_level_prime_max < 0) continue;
if (_level_prime_max == MIPS+1) {
_level_prime_max = 10000; // This is the default, after all!
}
const level_prime_max = _level_prime_max;
// ES 3.0.6 p150
let _level_max = level_prime_max;
if (tex.immutable) {
_level_max = Math.min(Math.max(level_base, level_prime_max), MIPS-1);
}
const level_max = _level_max;
const p = Math.floor(Math.log2(SIZE)) + level_base;
const q = Math.min(p, level_max);
debug(`\
level_prime_base/max: [${level_prime_base}, ${level_prime_max}] (inclusive)
level_base/max: [${level_base}, ${level_max}] (inclusive)
q: ${q}`);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_BASE_LEVEL,
level_prime_base);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAX_LEVEL,
level_prime_max);
const mipComplete = (q <= MIPS-1);
for (const [minFilter,useMips] of MIN_FILTERS) {
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER,
gl[minFilter]);
// ES3.0 p211
const srcMaxSampledMip = (useMips ? q : level_base);
// ES3.0 p160-161
const textureComplete = (srcMaxSampledMip <= MIPS-1) &&
(level_base <= level_max);
for (const magFilter of MAG_FILTERS) {
debug(`\
min: ${minFilter}, mag: ${magFilter}`);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER,
gl[magFilter]);
for (const dstMip of range(0,MIPS+1)) {
debug(`
mip: ${dstMip}`);
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0,
gl.TEXTURE_2D, tex, dstMip);
// -
// ES3.0 p213-214
let fbComplete = true;
// * "The width and height of `image` are non-zero"
fbComplete &= (0 <= dstMip && dstMip <= MIPS-1);
if (!tex.immutable) { // "...does not name an immutable-format texture..."
// * "...the value of [level] must be in the range `[level_base, q]`"
fbComplete &= (level_base <= dstMip && dstMip <= q);
// * "...the value of [level] is not `level_base`, then the texture must be mipmap complete"
if (dstMip != level_base) {
fbComplete &= mipComplete;
}
}
// -
let expectError = 0;
let expectStatus = gl.FRAMEBUFFER_COMPLETE;
// ES3.0 p211
let samplingFeedback = (level_base <= dstMip && dstMip <= srcMaxSampledMip);
if (!textureComplete) {
// Incomplete textures are safe
samplingFeedback = false;
}
if (samplingFeedback) {
expectError = gl.INVALID_OPERATION;
}
if (!fbComplete) {
expectStatus = gl.FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
expectError = gl.INVALID_FRAMEBUFFER_OPERATION;
}
// -
wtu.framebufferStatusShouldBe(gl, gl.FRAMEBUFFER,
expectStatus, `{immutable: ${tex.immutable}, level_prime_base/max: [${level_prime_base}, ${level_prime_max}], minFilter: ${minFilter}, dest: ${dstMip}}`);
gl.drawArrays(gl.POINTS, 0, 1);
wtu.glErrorShouldBe(gl, expectError, "after draw with texture");
}
}
}
}
}
}
})();
var successfullyParsed = true;
</script>
<script src="../../../js/js-test-post.js"></script>
</body>
</html>

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

@ -12,12 +12,6 @@ found in the LICENSE.txt file.
<link rel="stylesheet" href="../../../resources/js-test-style.css"/> <link rel="stylesheet" href="../../../resources/js-test-style.css"/>
<script src="../../../js/js-test-pre.js"></script> <script src="../../../js/js-test-pre.js"></script>
<script src="../../../js/webgl-test-utils.js"></script> <script src="../../../js/webgl-test-utils.js"></script>
</head>
<body>
<div id="description"></div>
<div id="console"></div>
<canvas id="canvas"></canvas>
<img id="img" style="display:none;">
<script> <script>
"use strict"; "use strict";
var wtu = WebGLTestUtils; var wtu = WebGLTestUtils;
@ -39,7 +33,7 @@ var localImgUrl = "../../../resources/opengl_logo.jpg";
var imgDomain; var imgDomain;
var pageDomain; var pageDomain;
function imageLoaded(img) { function imageLoaded() {
description("This test ensures WebGL2 implementations for OffscreenCanvas follow proper same-origin restrictions."); description("This test ensures WebGL2 implementations for OffscreenCanvas follow proper same-origin restrictions.");
if (!window.OffscreenCanvas) { if (!window.OffscreenCanvas) {
@ -48,6 +42,8 @@ function imageLoaded(img) {
return; return;
} }
var img = this;
assertMsg(img.width > 0 && img.height > 0, "img was loaded"); assertMsg(img.width > 0 && img.height > 0, "img was loaded");
imgDomain = wtu.getBaseDomain(wtu.getHost(img.src)); imgDomain = wtu.getBaseDomain(wtu.getHost(img.src));
pageDomain = wtu.getBaseDomain(window.location.host); pageDomain = wtu.getBaseDomain(window.location.host);
@ -130,17 +126,13 @@ function imageLoaded(img) {
finishTest(); finishTest();
} }
(async function() { wtu.setupImageForCrossOriginTest("#img", defaultImgUrl, localImgUrl, imageLoaded);
const img = document.getElementById('img');
try {
await wtu.awaitOrTimeout(wtu.loadCrossOriginImage(img, defaultImgUrl, localImgUrl), 1000);
} catch (e) {
testFailed(`Image setup failed (${e}).`);
finishTest();
return;
}
imageLoaded(img);
})();
</script> </script>
</head>
<body>
<div id="description"></div>
<div id="console"></div>
<canvas id="canvas"></canvas>
<img id="img" style="display:none;">
</body> </body>
</html> </html>

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

@ -41,7 +41,7 @@ gl.bindTexture(gl.TEXTURE_2D, tex);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB10_A2UI, 16, 16, 0, gl.RGBA_INTEGER, gl.UNSIGNED_INT_2_10_10_10_REV, null); gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB10_A2UI, 16, 16, 0, gl.RGBA_INTEGER, gl.UNSIGNED_INT_2_10_10_10_REV, null);
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Teximage2D taking a null array buffer should succeed"); wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Teximage2D taking a null array buffer should succeed");
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB10_A2UI, gl.RGBA_INTEGER, gl.UNSIGNED_INT_2_10_10_10_REV, c); gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB10_A2UI, gl.RGBA_INTEGER, gl.UNSIGNED_INT_2_10_10_10_REV, c);
wtu.glErrorShouldBe(gl, [gl.INVALID_VALUE, gl.INVALID_ENUM], "TexImage2D taking RGB10_A2UI internalformat and a canvas source should fail"); wtu.glErrorShouldBe(gl, gl.INVALID_VALUE, "TexImage2D taking RGB10_A2UI internalformat and a canvas source should fail");
gl.deleteTexture(tex); gl.deleteTexture(tex);
var successfullyParsed = true; var successfullyParsed = true;

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

@ -98,7 +98,7 @@ function runTexCompressedFormatsTest(texCompressedFormats)
// Test a 2D texture. // Test a 2D texture.
var tex = gl.createTexture(); var tex = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, tex); gl.bindTexture(gl.TEXTURE_2D, tex);
gl.texStorage2D(gl.TEXTURE_2D, 1, internalformat, 4, 4); gl.texStorage2D(gl.TEXTURE_2D, 1, internalformat, 1, 1);
wtu.glErrorShouldBe(gl, gl.NO_ERROR, wtu.glErrorShouldBe(gl, gl.NO_ERROR,
"texStorage2D should succeed for " + enumToString(internalformat)); "texStorage2D should succeed for " + enumToString(internalformat));
gl.deleteTexture(tex); gl.deleteTexture(tex);
@ -111,14 +111,14 @@ function runTexCompressedFormatsTest(texCompressedFormats)
// Test the 3D texture targets. // Test the 3D texture targets.
var tex3d = gl.createTexture(); var tex3d = gl.createTexture();
gl.bindTexture(gl.TEXTURE_3D, tex3d); gl.bindTexture(gl.TEXTURE_3D, tex3d);
gl.texStorage3D(gl.TEXTURE_3D, 1, internalformat, 4, 4, 1); gl.texStorage3D(gl.TEXTURE_3D, 1, internalformat, 1, 1, 1);
wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION,
"texStorage3D(TEXTURE_3D) should fail for " + enumToString(internalformat)); "texStorage3D(TEXTURE_3D) should fail for " + enumToString(internalformat));
gl.deleteTexture(tex3d); gl.deleteTexture(tex3d);
var tex2dArr = gl.createTexture(); var tex2dArr = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D_ARRAY, tex2dArr); gl.bindTexture(gl.TEXTURE_2D_ARRAY, tex2dArr);
gl.texStorage3D(gl.TEXTURE_2D_ARRAY, 1, internalformat, 4, 4, 1); gl.texStorage3D(gl.TEXTURE_2D_ARRAY, 1, internalformat, 1, 1, 1);
wtu.glErrorShouldBe(gl, gl.NO_ERROR, wtu.glErrorShouldBe(gl, gl.NO_ERROR,
"texStorage3D(TEXTURE_2D_ARRAY) should succeed for " + enumToString(internalformat)); "texStorage3D(TEXTURE_2D_ARRAY) should succeed for " + enumToString(internalformat));
wtu.clearAndDrawUnitQuad(gl); wtu.clearAndDrawUnitQuad(gl);

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

@ -9,7 +9,6 @@ fboinvalidate/00_test_list.txt
fborender/00_test_list.txt fborender/00_test_list.txt
fragmentoutput/00_test_list.txt fragmentoutput/00_test_list.txt
framebufferblit/00_test_list.txt framebufferblit/00_test_list.txt
multisample/00_test_list.txt
primitiverestart/00_test_list.txt primitiverestart/00_test_list.txt
shaderindexing/00_test_list.txt shaderindexing/00_test_list.txt
shadermatrix/00_test_list.txt shadermatrix/00_test_list.txt
@ -44,6 +43,7 @@ instancedrendering.html
integerstatequery.html integerstatequery.html
internalformatquery.html internalformatquery.html
lifetime.html lifetime.html
multisample.html
negativebufferapi.html negativebufferapi.html
negativefragmentapi.html negativefragmentapi.html
negativeshaderapi.html negativeshaderapi.html

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

@ -1713,7 +1713,7 @@ goog.scope(function() {
* Run test * Run test
* @param {WebGL2RenderingContext} context * @param {WebGL2RenderingContext} context
*/ */
es3fMultisampleTests.run = function(context, range) { es3fMultisampleTests.run = function(context) {
gl = context; gl = context;
//Set up Test Root parameters //Set up Test Root parameters
var testName = 'multisample'; var testName = 'multisample';
@ -1730,8 +1730,6 @@ goog.scope(function() {
try { try {
//Create test cases //Create test cases
es3fMultisampleTests.init(); es3fMultisampleTests.init();
if (range)
state.setRange(range);
//Run test cases //Run test cases
tcuTestCase.runTestCases(); tcuTestCase.runTestCases();
} }

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

@ -0,0 +1,24 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>WebGL Multisample 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="../../../closure-library/closure/goog/base.js"></script>
<script src="../../deqp-deps.js"></script>
<script>goog.require('functional.gles3.es3fMultisampleTests');</script>
</head>
<body>
<div id="description"></div>
<div id="console"></div>
<canvas id="canvas" width="256" height="256"> </canvas>
<script>
var wtu = WebGLTestUtils;
var gl = wtu.create3DContext('canvas', null, 2);
functional.gles3.es3fMultisampleTests.run(gl);
</script>
</body>
</html>

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

@ -1,6 +0,0 @@
# This file is auto-generated from multisample_test_generator.py
# DO NOT EDIT!
default_fbo.html
fbo_4_samples.html
fbo_8_samples.html
fbo_max_samples.html

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

@ -1,31 +0,0 @@
<!--
This file is auto-generated from multisample_test_generator.py
DO NOT EDIT!
-->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>WebGL Multisample 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="../../../../closure-library/closure/goog/base.js"></script>
<script src="../../../deqp-deps.js"></script>
<script>goog.require('functional.gles3.es3fMultisampleTests');</script>
</head>
<body>
<div id="description"></div>
<div id="console"></div>
<canvas id="canvas" width="256" height="256"> </canvas>
<script>
var wtu = WebGLTestUtils;
var gl = wtu.create3DContext('canvas', null, 2);
functional.gles3.es3fMultisampleTests.run(gl, [0, 1]);
</script>
</body>
</html>

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