mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 703927 - Upgrade WebGL conformance test suite to r16237 - no review
The canonical location for this testsuite is: https://cvs.khronos.org/svn/repos/registry/trunk/public/webgl/sdk/tests
This commit is contained in:
parent
a959069916
commit
bfff5f7f10
@ -1,4 +1,4 @@
|
||||
This is a local copy of the WebGL conformance suite, SVN revision 15981
|
||||
This is a local copy of the WebGL conformance suite, SVN revision 16237
|
||||
|
||||
The canonical location for this testsuite is:
|
||||
|
||||
|
@ -11,13 +11,15 @@ var wtu = WebGLTestUtils;
|
||||
var canvas;
|
||||
var gl;
|
||||
var shouldGenerateGLError;
|
||||
var extension_name = "WEBKIT_lose_context";
|
||||
var extension_name = "WEBGL_EXT_lose_context";
|
||||
var extension;
|
||||
var bufferObjects;
|
||||
var program;
|
||||
var texture;
|
||||
var texColor = [255, 10, 20, 255];
|
||||
var allowRestore;
|
||||
var contextLostEventFired;
|
||||
var contextRestoredEventFired;
|
||||
|
||||
function init()
|
||||
{
|
||||
@ -28,15 +30,14 @@ function init()
|
||||
description("Tests behavior under a restored context.");
|
||||
|
||||
shouldGenerateGLError = wtu.shouldGenerateGLError;
|
||||
runTests();
|
||||
testLosingContext();
|
||||
}
|
||||
|
||||
function runTests()
|
||||
function runTest1()
|
||||
{
|
||||
testLosingContext();
|
||||
testLosingAndRestoringContext();
|
||||
|
||||
finish();
|
||||
finishTest();
|
||||
}
|
||||
|
||||
function setupTest()
|
||||
@ -56,35 +57,75 @@ function setupTest()
|
||||
function testLosingContext()
|
||||
{
|
||||
if (!setupTest())
|
||||
return;
|
||||
finishTest();
|
||||
|
||||
debug("Test losing a context and inability to restore it.");
|
||||
|
||||
canvas.addEventListener("webglcontextlost", testLostContext);
|
||||
canvas.addEventListener("webglcontextlost", function() {
|
||||
testLostContext();
|
||||
// restore the context after this event has exited.
|
||||
setTimeout(function() {
|
||||
// we didn't call prevent default so we should not be able to restore the context
|
||||
shouldGenerateGLError(gl, gl.INVALID_OPERATION, "extension.restoreContext()");
|
||||
testLosingAndRetoreingContext();
|
||||
}, 1);
|
||||
});
|
||||
canvas.addEventListener("webglcontextrestored", testShouldNotRestoreContext);
|
||||
allowRestore = false;
|
||||
contextLostEventFired = false;
|
||||
contextRestoredEventFired = false;
|
||||
|
||||
testOriginalContext();
|
||||
extension.loseContext();
|
||||
shouldGenerateGLError(gl, gl.INVALID_OPERATION, "extension.restoreContext()");
|
||||
debug("");
|
||||
// The context should be lost immediately.
|
||||
shouldBeTrue("gl.isContextLost()");
|
||||
shouldBe("gl.getError()", "gl.CONTEXT_LOST_WEBGL");
|
||||
shouldBe("gl.getError()", "gl.NO_ERROR");
|
||||
// gl methods should be no-ops
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, gl.blendFunc(gl.TEXTURE_2D, gl.TEXTURE_CUBE_MAP));
|
||||
// but the event should not have been fired.
|
||||
shouldBeFalse("contextLostEventFired");
|
||||
}
|
||||
|
||||
function testLosingAndRestoringContext()
|
||||
{
|
||||
if (!setupTest())
|
||||
return;
|
||||
finishTest();
|
||||
|
||||
debug("");
|
||||
debug("Test losing and restoring a context.");
|
||||
|
||||
canvas.addEventListener("webglcontextlost", testLostContext);
|
||||
canvas.addEventListener("webglcontextrestored", testRestoredContext);
|
||||
canvas.addEventListener("webglcontextlost", function() {
|
||||
testLostContext();
|
||||
// restore the context after this event has exited.
|
||||
setTimeout(function() {
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, "extension.restoreContext()");
|
||||
// The context should still be lost. It will not get restored until the
|
||||
// webglrestorecontext event is fired.
|
||||
shouldBeTrue("gl.isContextLost()");
|
||||
shouldBe("gl.getError()", "gl.NO_ERROR");
|
||||
// gl methods should still be no-ops
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, gl.blendFunc(gl.TEXTURE_2D, gl.TEXTURE_CUBE_MAP));
|
||||
}, 1);
|
||||
});
|
||||
canvas.addEventListener("webglcontextrestored", function() {
|
||||
testRestoredContext();
|
||||
finishTest();
|
||||
});
|
||||
allowRestore = true;
|
||||
contextLostEventFired = false;
|
||||
contextRestoredEventFired = false;
|
||||
|
||||
testOriginalContext();
|
||||
extension.loseContext();
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, "extension.restoreContext()");
|
||||
debug("");
|
||||
// The context should be lost immediately.
|
||||
shouldBeTrue("gl.isContextLost()");
|
||||
shouldBe("gl.getError()", "gl.CONTEXT_LOST_WEBGL");
|
||||
shouldBe("gl.getError()", "gl.NO_ERROR");
|
||||
// gl methods should be no-ops
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, gl.blendFunc(gl.TEXTURE_2D, gl.TEXTURE_CUBE_MAP));
|
||||
// but the event should not have been fired.
|
||||
shouldBeFalse("contextLostEventFired");
|
||||
}
|
||||
|
||||
function testRendering()
|
||||
@ -118,12 +159,13 @@ function testOriginalContext()
|
||||
function testLostContext(e)
|
||||
{
|
||||
debug("Test lost context");
|
||||
shouldBeFalse("contextLostEventFired");
|
||||
contextLostEventFired = true;
|
||||
shouldBeTrue("gl.isContextLost()");
|
||||
shouldBe("gl.getError()", "gl.CONTEXT_LOST_WEBGL");
|
||||
shouldBe("gl.getError()", "gl.NO_ERROR");
|
||||
debug("");
|
||||
if (allowRestore)
|
||||
e.preventDefault();
|
||||
if (allowRestore)
|
||||
e.preventDefault();
|
||||
}
|
||||
|
||||
function testShouldNotRestoreContext(e)
|
||||
@ -147,6 +189,8 @@ function testResources(expected)
|
||||
function testRestoredContext()
|
||||
{
|
||||
debug("Test restored context");
|
||||
shouldBeFalse("contextRestoredEventFired");
|
||||
contextRestoredEventFired = true;
|
||||
shouldBeFalse("gl.isContextLost()");
|
||||
shouldBe("gl.getError()", "gl.NO_ERROR");
|
||||
|
||||
@ -160,16 +204,6 @@ function testRestoredContext()
|
||||
debug("");
|
||||
}
|
||||
|
||||
function finish() {
|
||||
successfullyParsed = true;
|
||||
var epilogue = document.createElement("script");
|
||||
epilogue.onload = function() {
|
||||
if (window.nonKhronosFrameworkNotifyDone)
|
||||
window.nonKhronosFrameworkNotifyDone();
|
||||
};
|
||||
epilogue.src = "../../resources/js-test-post.js";
|
||||
document.body.appendChild(epilogue);
|
||||
}
|
||||
|
||||
</script>
|
||||
</head>
|
||||
|
@ -11,7 +11,7 @@ var wtu;
|
||||
var canvas;
|
||||
var gl;
|
||||
var shouldGenerateGLError;
|
||||
var extension_name = "WEBKIT_lose_context";
|
||||
var extension_name = "WEBGL_EXT_lose_context";
|
||||
var extension;
|
||||
|
||||
var buffer;
|
||||
@ -51,7 +51,7 @@ function init()
|
||||
extension = gl.getExtension(extension_name);
|
||||
if (!extension) {
|
||||
debug(extension_name + " extension not found.");
|
||||
finish();
|
||||
finishTest();
|
||||
return;
|
||||
}
|
||||
|
||||
@ -65,8 +65,8 @@ function loseContext()
|
||||
debug("");
|
||||
debug("Lose context");
|
||||
|
||||
// Note: this will cause the context to be lost, and the
|
||||
// webglcontextlost event listener to be called, immediately.
|
||||
// Note: this will cause the context to be lost, but the
|
||||
// webglcontextlost event listener to be queued.
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, "extension.loseContext()");
|
||||
debug("");
|
||||
}
|
||||
@ -302,19 +302,9 @@ function testLostContext()
|
||||
|
||||
debug("");
|
||||
|
||||
finish();
|
||||
finishTest();
|
||||
}
|
||||
|
||||
function finish() {
|
||||
successfullyParsed = true;
|
||||
var epilogue = document.createElement("script");
|
||||
epilogue.onload = function() {
|
||||
if (window.nonKhronosFrameworkNotifyDone)
|
||||
window.nonKhronosFrameworkNotifyDone();
|
||||
};
|
||||
epilogue.src = "../../resources/js-test-post.js";
|
||||
document.body.appendChild(epilogue);
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body onload="init()">
|
||||
|
@ -3,4 +3,6 @@ oes-texture-float.html
|
||||
oes-vertex-array-object.html
|
||||
webgl-debug-renderer-info.html
|
||||
webgl-debug-shaders.html
|
||||
# commented out until 1.0.1 cut
|
||||
# webgl-experimental-compressed-textures.html
|
||||
|
||||
|
@ -0,0 +1,3 @@
|
||||
var img_4x4_rgb_dxt1 = [
|
||||
0xe0,0x07,0x00,0xf8,0x11,0x10,0x15,0x00,
|
||||
];
|
@ -0,0 +1,3 @@
|
||||
var img_4x4_rgba_dxt1 = [
|
||||
0xe0,0x07,0x00,0xf8,0x13,0x10,0x15,0x00,
|
||||
];
|
@ -0,0 +1,3 @@
|
||||
var img_4x4_rgba_dxt3 = [
|
||||
0xf6,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0xf8,0xe0,0x07,0x44,0x45,0x40,0x55,
|
||||
];
|
@ -0,0 +1,3 @@
|
||||
var img_4x4_rgba_dxt5 = [
|
||||
0xf6,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0xf8,0xe0,0x07,0x44,0x45,0x40,0x55,
|
||||
];
|
@ -0,0 +1,3 @@
|
||||
var img_4x4_rgba_raw = [
|
||||
0xff,0x00,0x00,0x69,0x00,0xff,0x00,0xff,0xff,0x00,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0x00,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0x00,0x00,0xff,0xff,0x00,0x00,0xff,0xff,0x00,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,
|
||||
];
|
@ -0,0 +1,3 @@
|
||||
var img_8x8_rgb_dxt1 = [
|
||||
0xe0,0x07,0x00,0xf8,0x11,0x10,0x15,0x00,0x1f,0x00,0xe0,0xff,0x11,0x10,0x15,0x00,0xe0,0x07,0x1f,0xf8,0x44,0x45,0x40,0x55,0x1f,0x00,0xff,0x07,0x44,0x45,0x40,0x55,
|
||||
];
|
@ -0,0 +1,3 @@
|
||||
var img_8x8_rgba_dxt1 = [
|
||||
0xe0,0x07,0x00,0xf8,0x13,0x13,0x15,0x00,0x1f,0x00,0xe0,0xff,0x11,0x10,0x15,0x00,0xe0,0x07,0x1f,0xf8,0x44,0x45,0x43,0x57,0x1f,0x00,0xff,0x07,0x44,0x45,0x40,0x55,
|
||||
];
|
@ -0,0 +1,3 @@
|
||||
var img_8x8_rgba_dxt3 = [
|
||||
0xf6,0xff,0xf6,0xff,0xff,0xff,0xff,0xff,0x00,0xf8,0xe0,0x07,0x44,0x45,0x40,0x55,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xe0,0xff,0x1f,0x00,0x44,0x45,0x40,0x55,0xff,0xff,0xff,0xff,0xf6,0xff,0xf6,0xff,0x1f,0xf8,0xe0,0x07,0x11,0x10,0x15,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x07,0x1f,0x00,0x11,0x10,0x15,0x00,
|
||||
];
|
@ -0,0 +1,3 @@
|
||||
var img_8x8_rgba_dxt5 = [
|
||||
0xff,0x69,0x01,0x10,0x00,0x00,0x00,0x00,0x00,0xf8,0xe0,0x07,0x44,0x45,0x40,0x55,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0xff,0x1f,0x00,0x44,0x45,0x40,0x55,0xff,0x69,0x00,0x00,0x00,0x01,0x10,0x00,0x1f,0xf8,0xe0,0x07,0x11,0x10,0x15,0x00,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x07,0x1f,0x00,0x11,0x10,0x15,0x00,
|
||||
];
|
@ -0,0 +1,3 @@
|
||||
var img_8x8_rgba_pvrtc4bpp = [
|
||||
0x33,0x30,0x3f,0x00,0xe0,0x83,0x00,0xfc,0xcc,0xcf,0xc0,0xff,0xe0,0x83,0x1f,0xfc,0xcc,0xcf,0xc0,0xff,0xe0,0xff,0x1f,0x80,0x33,0x30,0x3f,0x00,0xfe,0x83,0x1f,0x80,
|
||||
];
|
@ -0,0 +1,3 @@
|
||||
var img_8x8_rgba_raw = [
|
||||
0xff,0x00,0x00,0x69,0x00,0xff,0x00,0xff,0xff,0x00,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x00,0x00,0xff,0xff,0xff,0xff,0x00,0xff,0x00,0x00,0xff,0xff,0x00,0xff,0x00,0x69,0x00,0xff,0x00,0xff,0xff,0x00,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0x00,0xff,0xff,0x00,0x00,0xff,0xff,0xff,0xff,0x00,0xff,0x00,0x00,0xff,0xff,0xff,0x00,0x00,0xff,0xff,0x00,0x00,0xff,0xff,0x00,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x00,0x00,0xff,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0x00,0xff,0xff,0x00,0x00,0xff,0xff,0x00,0x00,0xff,0xff,0x00,0x00,0xff,0xff,0x00,0xff,0x00,0xff,0xff,0x00,0xff,0xff,0x00,0xff,0x00,0xff,0xff,0x00,0xff,0xff,0x00,0x00,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0x00,0xff,0xff,0x00,0xff,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0x00,0xff,0x00,0xff,0xff,0x00,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0x00,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0x00,0x69,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0xff,0x00,0xff,0xff,0x00,0x00,0xff,0xff,0x00,0x00,0xff,0xff,0x00,0x00,0xff,0xff,0x00,0xff,0xff,0xff,0xff,0x00,0xff,0x69,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,
|
||||
];
|
@ -0,0 +1,520 @@
|
||||
<!--
|
||||
Copyright (c) 2011 The Chromium Authors. All rights reserved.
|
||||
Use of this source code is governed by a BSD-style license that can be
|
||||
found in the LICENSE file.
|
||||
-->
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>WebGL WEBGL_EXPERIMENTAL_compressed_textures Conformance Tests</title>
|
||||
<link rel="stylesheet" href="../../resources/js-test-style.css"/>
|
||||
<style>
|
||||
img {
|
||||
border: 1px solid black;
|
||||
margin-right: 1em;
|
||||
}
|
||||
.testimages {
|
||||
}
|
||||
|
||||
.testimages br {
|
||||
clear: both;
|
||||
}
|
||||
|
||||
.testimages > div {
|
||||
float: left;
|
||||
margin: 1em;
|
||||
}
|
||||
</style>
|
||||
<script src="../../resources/desktop-gl-constants.js" type="text/javascript"></script>
|
||||
<script src="../../resources/js-test-pre.js"></script>
|
||||
<script src="../resources/webgl-test.js"></script>
|
||||
<script src="../resources/webgl-test-utils.js"></script>
|
||||
<script src="compressed-textures/4x4.rgb.dxt1.js"></script>
|
||||
<script src="compressed-textures/4x4.rgba.dxt1.js"></script>
|
||||
<script src="compressed-textures/4x4.rgba.dxt5.js"></script>
|
||||
<script src="compressed-textures/8x8.rgb.dxt1.js"></script>
|
||||
<script src="compressed-textures/8x8.rgba.dxt1.js"></script>
|
||||
<script src="compressed-textures/8x8.rgba.dxt5.js"></script>
|
||||
<script src="compressed-textures/8x8.rgba.pvrtc4bpp.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="description"></div>
|
||||
<canvas id="canvas" width="8" height="8" style="width: 8px; height: 8px;"></canvas>
|
||||
<div id="console"></div>
|
||||
<!-- Shaders for testing standard derivatives -->
|
||||
<script>
|
||||
description("This test verifies the functionality of the OES_vertex_array_object extension, if it is available.");
|
||||
|
||||
debug("");
|
||||
|
||||
var wtu = WebGLTestUtils;
|
||||
var canvas = document.getElementById("canvas");
|
||||
var gl = wtu.create3DContext(canvas, {antialias: false});
|
||||
var program = wtu.setupTexturedQuad(gl);
|
||||
var ext = null;
|
||||
var vao = null;
|
||||
var validFormats = {
|
||||
COMPRESSED_RGB_S3TC_DXT1_EXT : 0x83F0,
|
||||
COMPRESSED_RGBA_S3TC_DXT1_EXT : 0x83F1,
|
||||
COMPRESSED_RGBA_S3TC_DXT5_EXT : 0x83F3,
|
||||
ETC1_RGB8_OES : 0x8D64,
|
||||
COMPRESSED_RGB_PVRTC_4BPPV1_IMG : 0x8C00,
|
||||
COMPRESSED_RGBA_PVRTC_4BPPV1_IMG : 0x8C02
|
||||
};
|
||||
var name;
|
||||
var supportedFormats;
|
||||
|
||||
if (!gl) {
|
||||
testFailed("WebGL context does not exist");
|
||||
} else {
|
||||
testPassed("WebGL context exists");
|
||||
|
||||
// Run tests with extension disabled
|
||||
runTestDisabled();
|
||||
|
||||
// Query the extension and store globally so shouldBe can access it
|
||||
ext = gl.getExtension("WEBGL_EXPERIMENTAL_compressed_textures");
|
||||
if (!ext) {
|
||||
testPassed("No WEBGL_EXPERIMENTAL_compressed_textures support -- this is legal");
|
||||
runSupportedTest(false);
|
||||
} else {
|
||||
testPassed("Successfully enabled WEBGL_EXPERIMENTAL_compressed_textures extension");
|
||||
|
||||
runSupportedTest(true);
|
||||
runTestExtension();
|
||||
}
|
||||
}
|
||||
|
||||
function runSupportedTest(extensionEnabled) {
|
||||
var supported = gl.getSupportedExtensions();
|
||||
if (supported.indexOf("WEBGL_EXPERIMENTAL_compressed_textures") >= 0) {
|
||||
if (extensionEnabled) {
|
||||
testPassed("WEBGL_EXPERIMENTAL_compressed_textures listed as supported and getExtension succeeded");
|
||||
} else {
|
||||
testFailed("WEBGL_EXPERIMENTAL_compressed_textures listed as supported but getExtension failed");
|
||||
}
|
||||
} else {
|
||||
if (extensionEnabled) {
|
||||
testFailed("WEBGL_EXPERIMENTAL_compressed_textures not listed as supported but getExtension succeeded");
|
||||
} else {
|
||||
testPassed("WEBGL_EXPERIMENTAL_compressed_textures not listed as supported and getExtension failed -- this is legal");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function runTestDisabled() {
|
||||
debug("Testing binding enum with extension disabled");
|
||||
|
||||
// Default value is null
|
||||
if (gl.getParameter(gl.COMPRESSED_TEXTURE_FORMATS) === null) {
|
||||
testPassed("Default value of COMPRESSED_TEXTURE_FORMATS is null");
|
||||
} else {
|
||||
testFailed("Default value of COMPRESSED_TEXTURE_FORMATS is not null");
|
||||
}
|
||||
}
|
||||
|
||||
function checkIsValidFormat(format) {
|
||||
for (var name in validFormats) {
|
||||
if (format == validFormats[name]) {
|
||||
testPassed("supported format " + formatToString(format) + " is valid");
|
||||
return;
|
||||
}
|
||||
}
|
||||
testFailed("supported format " + formatToString(format) + " is not valid");
|
||||
}
|
||||
|
||||
function formatToString(format) {
|
||||
for (var p in ext) {
|
||||
if (ext[p] == format) {
|
||||
return p;
|
||||
}
|
||||
}
|
||||
return "0x" + format.toString(16);
|
||||
}
|
||||
|
||||
function runTestExtension() {
|
||||
debug("Testing WEBGL_EXPERIMENTAL_compressed_textures");
|
||||
|
||||
// check that all format enums exist.
|
||||
for (name in validFormats) {
|
||||
var expected = "0x" + validFormats[name].toString(16);
|
||||
var actual = "ext['" + name + "']";
|
||||
shouldBe(actual, expected);
|
||||
}
|
||||
|
||||
supportedFormats = gl.getParameter(gl.COMPRESSED_TEXTURE_FORMATS);
|
||||
// Even if no formats are supported this should return an array.
|
||||
shouldBeTrue("supportedFormats.length !== undefined");
|
||||
|
||||
// check that each format is an allowed format
|
||||
for (var ii = 0; ii < supportedFormats.length; ++ii) {
|
||||
checkIsValidFormat(supportedFormats[ii]);
|
||||
}
|
||||
|
||||
// Test each format
|
||||
for (var ii = 0; ii < supportedFormats.length; ++ii) {
|
||||
switch (supportedFormats[ii]) {
|
||||
case ext.COMPRESSED_RGB_S3TC_DXT1_EXT:
|
||||
testDXT1_RGB();
|
||||
break;
|
||||
case ext.COMPRESSED_RGBA_S3TC_DXT1_EXT:
|
||||
testDXT1_RGBA();
|
||||
break;
|
||||
case ext.COMPRESSED_RGBA_S3TC_DXT5_EXT:
|
||||
testDXT5_RGBA();
|
||||
break;
|
||||
case ext.ETC1_RGB8_OES:
|
||||
testETC1_RGB8();
|
||||
break;
|
||||
case ext.COMPRESSED_RGB_PVRTC_4BPPV1_IMG:
|
||||
testPVRTC_RGB_4BPPV1();
|
||||
break;
|
||||
case ext.COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:
|
||||
testPVRTC_RGBA_4BPPV1();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function testDXT1_RGB() {
|
||||
var tests = [
|
||||
{ width: 4,
|
||||
height: 4,
|
||||
channels: 3,
|
||||
data: img_4x4_rgb_dxt1,
|
||||
format: ext.COMPRESSED_RGB_S3TC_DXT1_EXT
|
||||
},
|
||||
{ width: 8,
|
||||
height: 8,
|
||||
channels: 3,
|
||||
data: img_8x8_rgb_dxt1,
|
||||
format: ext.COMPRESSED_RGB_S3TC_DXT1_EXT
|
||||
}
|
||||
];
|
||||
testDXTTextures(tests);
|
||||
}
|
||||
|
||||
function testDXT1_RGBA() {
|
||||
var tests = [
|
||||
{ width: 4,
|
||||
height: 4,
|
||||
channels: 4,
|
||||
data: img_4x4_rgba_dxt1,
|
||||
format: ext.COMPRESSED_RGBA_S3TC_DXT1_EXT
|
||||
},
|
||||
{ width: 8,
|
||||
height: 8,
|
||||
channels: 4,
|
||||
data: img_8x8_rgba_dxt1,
|
||||
format: ext.COMPRESSED_RGBA_S3TC_DXT1_EXT
|
||||
}
|
||||
];
|
||||
testDXTTextures(tests);
|
||||
}
|
||||
|
||||
function testDXT5_RGBA() {
|
||||
var tests = [
|
||||
{ width: 4,
|
||||
height: 4,
|
||||
channels: 4,
|
||||
data: img_4x4_rgba_dxt5,
|
||||
format: ext.COMPRESSED_RGBA_S3TC_DXT5_EXT
|
||||
},
|
||||
{ width: 8,
|
||||
height: 8,
|
||||
channels: 4,
|
||||
data: img_8x8_rgba_dxt5,
|
||||
format: ext.COMPRESSED_RGBA_S3TC_DXT5_EXT
|
||||
}
|
||||
];
|
||||
testDXTTextures(tests);
|
||||
}
|
||||
|
||||
function testETC1_RGB8() {
|
||||
testFailed("ETC1 test not yet implemented");
|
||||
}
|
||||
|
||||
function testPVRTC_RGB_4BPPV1() {
|
||||
var tests = [
|
||||
{ width: 8,
|
||||
height: 8,
|
||||
channels: 4,
|
||||
data: img_8x8_rgba_pvrtc4bpp,
|
||||
format: ext.COMPRESSED_RGB_PVRTC_4BPPV1_IMG
|
||||
}
|
||||
];
|
||||
testPVRTCTextures(tests);
|
||||
}
|
||||
|
||||
function testPVRTC_RGB_4BPPV1() {
|
||||
var tests = [
|
||||
{ width: 8,
|
||||
height: 8,
|
||||
channels: 4,
|
||||
data: img_8x8_rgba_pvrtc4bpp,
|
||||
format: ext.COMPRESSED_RGBA_PVRTC_4BPPV1_IMG
|
||||
}
|
||||
];
|
||||
testPVRTCTextures(tests);
|
||||
}
|
||||
|
||||
function testDXTTextures(tests) {
|
||||
debug("<hr/>");
|
||||
for (var ii = 0; ii < tests.length; ++ii) {
|
||||
testDXTTexture(tests[ii]);
|
||||
}
|
||||
}
|
||||
|
||||
function uncompressDXTBlock(
|
||||
destBuffer, destX, destY, destWidth, src, srcOffset, format) {
|
||||
function make565(src, offset) {
|
||||
return src[offset + 0] + src[offset + 1] * 256;
|
||||
}
|
||||
function make8888From565(c) {
|
||||
return [
|
||||
Math.floor(((c >> 11) & 0x1F) * 255 / 31),
|
||||
Math.floor(((c >> 5) & 0x3F) * 255 / 63),
|
||||
Math.floor(((c >> 0) & 0x1F) * 255 / 31),
|
||||
255
|
||||
];
|
||||
}
|
||||
function mix(mult, c0, c1, div) {
|
||||
var r = [];
|
||||
for (var ii = 0; ii < c0.length; ++ii) {
|
||||
r[ii] = Math.floor((c0[ii] * mult + c1[ii]) / div);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
var colorOffset =
|
||||
srcOffset + ((format == ext.COMPRESSED_RGBA_S3TC_DXT5_EXT) ? 8 : 0);
|
||||
var color0 = make565(src, colorOffset + 0);
|
||||
var color1 = make565(src, colorOffset + 2);
|
||||
var c0gtc1 = color0 > color1 || format == ext.COMPRESSED_RGBA_S3TC_DXT5_EXT;
|
||||
var rgba0 = make8888From565(color0);
|
||||
var rgba1 = make8888From565(color1);
|
||||
var colors = [
|
||||
rgba0,
|
||||
rgba1,
|
||||
c0gtc1 ? mix(2, rgba0, rgba1, 3) : mix(1, rgba0, rgba1, 2),
|
||||
c0gtc1 ? mix(2, rgba1, rgba0, 3) : [0, 0, 0, 255]
|
||||
];
|
||||
|
||||
// yea I know there is a lot of math in this inner loop.
|
||||
// so sue me.
|
||||
for (var yy = 0; yy < 4; ++yy) {
|
||||
var pixels = src[colorOffset + 4 + yy];
|
||||
for (var xx = 0; xx < 4; ++xx) {
|
||||
var dstOff = ((destY + yy) * destWidth + destX + xx) * 4;
|
||||
var code = (pixels >> (xx * 2)) & 0x3;
|
||||
var srcColor = colors[code];
|
||||
var 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_DXT5_EXT:
|
||||
{
|
||||
var alpha0 = src[srcOffset + 0];
|
||||
var alpha1 = src[srcOffset + 1];
|
||||
var alphaOff = Math.floor(yy / 2) * 3 + 2;
|
||||
var alphaBits =
|
||||
src[srcOffset + alphaOff + 0] +
|
||||
src[srcOffset + alphaOff + 1] * 256 +
|
||||
src[srcOffset + alphaOff + 2] * 65536;
|
||||
var alphaShift = (yy % 2) * 12 + xx * 3;
|
||||
var alphaCode = (alphaBits >> alphaShift) & 0x7;
|
||||
if (alpha0 > alpha1) {
|
||||
switch (alphaCode) {
|
||||
case 0:
|
||||
alpha = alpha0;
|
||||
break;
|
||||
case 1:
|
||||
alpha = alpha1;
|
||||
break;
|
||||
default:
|
||||
alpha = ((8 - alphaCode) * alpha0 + (alphaCode - 1) * alpha1) / 7;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
switch (alphaCode) {
|
||||
case 0:
|
||||
alpha = alpha0;
|
||||
break;
|
||||
case 1:
|
||||
alpha = alpha1;
|
||||
break;
|
||||
case 6:
|
||||
alpha = 0;
|
||||
break;
|
||||
case 7:
|
||||
alpha = 255;
|
||||
break;
|
||||
default:
|
||||
alpha = ((6 - alphaCode) * alpha0 + (alphaCode - 1) * alpha1) / 5;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw "bad format";
|
||||
}
|
||||
destBuffer[dstOff + 0] = srcColor[0];
|
||||
destBuffer[dstOff + 1] = srcColor[1];
|
||||
destBuffer[dstOff + 2] = srcColor[2];
|
||||
destBuffer[dstOff + 3] = alpha;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function uncompressDXT(width, height, data, format) {
|
||||
if (width % 4 || height % 4) throw "bad width or height";
|
||||
|
||||
var dest = new Uint8Array(width * height * 4);
|
||||
var blocksAcross = width / 4;
|
||||
var blocksDown = height / 4;
|
||||
var blockSize = (format == ext.COMPRESSED_RGBA_S3TC_DXT5_EXT ? 16 : 8);
|
||||
for (var yy = 0; yy < blocksDown; ++yy) {
|
||||
for (var xx = 0; xx < blocksAcross; ++xx) {
|
||||
uncompressDXTBlock(
|
||||
dest, xx * 4, yy * 4, width, data,
|
||||
(yy * blocksAcross + xx) * blockSize, format);
|
||||
}
|
||||
}
|
||||
return dest;
|
||||
}
|
||||
|
||||
function testDXTTexture(test) {
|
||||
var uncompressedData = uncompressDXT(
|
||||
test.width, test.height, test.data, test.format);
|
||||
|
||||
var inner = 4; //test.width == 4 ? 4 : 1
|
||||
for (var ii = 0; ii < inner; ++ii) {
|
||||
var width = test.width - ii;
|
||||
var height = test.height - ii;
|
||||
canvas.width = width;
|
||||
canvas.height = height;
|
||||
gl.viewport(0, 0, width, height);
|
||||
debug("testing " + formatToString(test.format) + " " +
|
||||
width + "x" + height);
|
||||
var tex = gl.createTexture();
|
||||
gl.bindTexture(gl.TEXTURE_2D, tex);
|
||||
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);
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
|
||||
ext.compressedTexImage2D(
|
||||
gl.TEXTURE_2D, 0, test.format, width, height, 0,
|
||||
new Uint8Array(test.data));
|
||||
glErrorShouldBe(gl, gl.NO_ERROR, "uploading compressed texture");
|
||||
wtu.drawQuad(gl);
|
||||
compareRect(
|
||||
width, height, test.channels, test.width, test.height, uncompressedData,
|
||||
test.data, test.format);
|
||||
}
|
||||
|
||||
gl.compressedTexImage2D(
|
||||
gl.TEXTURE_2D, 0, test.format, width + 1, height, 0,
|
||||
new Uint8Array(test.data));
|
||||
glErrorShouldBe(
|
||||
gl, gl.INVALID_OPERATION, "data size does not match dimensions");
|
||||
|
||||
|
||||
// TODO: test compressedTexSubImage2D
|
||||
// TODO: test invalid width, height, xoffset, yoffset
|
||||
}
|
||||
|
||||
function insertImg(element, caption, img) {
|
||||
var div = document.createElement("div");
|
||||
div.appendChild(img);
|
||||
var label = document.createElement("div");
|
||||
label.appendChild(document.createTextNode(caption));
|
||||
div.appendChild(label);
|
||||
element.appendChild(div);
|
||||
}
|
||||
|
||||
function makeImage(imageWidth, imageHeight, dataWidth, data, alpha) {
|
||||
var scale = 8;
|
||||
var c = document.createElement("canvas");
|
||||
c.width = imageWidth * scale;
|
||||
c.height = imageHeight * scale;
|
||||
var ctx = c.getContext("2d");
|
||||
for (var yy = 0; yy < imageWidth; ++yy) {
|
||||
for (var xx = 0; xx < imageHeight; ++xx) {
|
||||
var offset = (yy * dataWidth + xx) * 4;
|
||||
ctx.fillStyle = "rgba(" +
|
||||
data[offset + 0] + "," +
|
||||
data[offset + 1] + "," +
|
||||
data[offset + 2] + "," +
|
||||
(alpha ? data[offset + 3] / 255 : 1) + ")";
|
||||
ctx.fillRect(xx * scale, yy * scale, scale, scale);
|
||||
}
|
||||
}
|
||||
var img = document.createElement("img");
|
||||
img.src = c.toDataURL();
|
||||
return img;
|
||||
}
|
||||
function compareRect(
|
||||
actualWidth, actualHeight, actualChannels,
|
||||
dataWidth, dataHeight, expectedData,
|
||||
testData, testFormat) {
|
||||
var actual = new Uint8Array(actualWidth * actualHeight * 4);
|
||||
gl.readPixels(
|
||||
0, 0, actualWidth, actualHeight, gl.RGBA, gl.UNSIGNED_BYTE, actual);
|
||||
|
||||
var div = document.createElement("div");
|
||||
div.className = "testimages";
|
||||
insertImg(div, "expected", makeImage(
|
||||
actualWidth, actualHeight, dataWidth, expectedData,
|
||||
actualChannels == 4));
|
||||
insertImg(div, "actual", makeImage(
|
||||
actualWidth, actualHeight, actualWidth, actual,
|
||||
actualChannels == 4));
|
||||
div.appendChild(document.createElement('br'));
|
||||
document.getElementById("console").appendChild(div);
|
||||
|
||||
var failed = false;
|
||||
for (var yy = 0; yy < actualHeight; ++yy) {
|
||||
for (var xx = 0; xx < actualWidth; ++xx) {
|
||||
var actualOffset = (yy * actualWidth + xx) * 4;
|
||||
var expectedOffset = (yy * dataWidth + xx) * 4;
|
||||
var expected = [
|
||||
expectedData[expectedOffset + 0],
|
||||
expectedData[expectedOffset + 1],
|
||||
expectedData[expectedOffset + 2],
|
||||
(actualChannels == 3 ? 255 : expectedData[expectedOffset + 3])
|
||||
];
|
||||
for (var jj = 0; jj < 4; ++jj) {
|
||||
if (actual[actualOffset + jj] != expected[jj]) {
|
||||
failed = true;
|
||||
var was = actual[actualOffset + 0].toString();
|
||||
for (j = 1; j < 4; ++j) {
|
||||
was += "," + actual[actualOffset + j];
|
||||
}
|
||||
testFailed('at (' + xx + ', ' + yy +
|
||||
') expected: ' + expected + ' was ' + was);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!failed) {
|
||||
testPassed("texture rendered correctly");
|
||||
}
|
||||
}
|
||||
|
||||
function testPVRTCTextures() {
|
||||
testFailed("PVRTC test not yet implemented");
|
||||
}
|
||||
|
||||
debug("");
|
||||
successfullyParsed = true;
|
||||
</script>
|
||||
<script src="../../resources/js-test-post.js"></script>
|
||||
|
||||
</body>
|
||||
</html>
|
@ -25,6 +25,7 @@ GLSLGenerator.runFeatureTest({
|
||||
args: "$(type) p1, $(type) p2",
|
||||
baseArgs: "value$(field)",
|
||||
testFunc: "$(func)($(type),$(type))",
|
||||
fragmentTolerance: 1,
|
||||
emuFuncs: [
|
||||
{ type: "float",
|
||||
code: [
|
||||
|
@ -25,6 +25,7 @@ GLSLGenerator.runFeatureTest({
|
||||
args: "$(type) value",
|
||||
baseArgs: "value$(field)",
|
||||
testFunc: "$(func)($(type))",
|
||||
fragmentTolerance: 1,
|
||||
emuFuncs: [
|
||||
{ type: "float",
|
||||
code: [
|
||||
|
@ -24,6 +24,7 @@ GLSLGenerator.runFeatureTest({
|
||||
args: "$(type) value, float divisor",
|
||||
baseArgs: "value$(field), divisor",
|
||||
testFunc: "$(func)($(arg0), float)",
|
||||
fragmentTolerance: 1,
|
||||
emuFunc: ["float $(func)_base(float value, float divisor) {",
|
||||
" return value - divisor * floor(value / divisor);",
|
||||
"}"].join("\n"),
|
||||
|
@ -32,6 +32,7 @@ var fragmentShader = wtu.loadStandardFragmentShader(gl);
|
||||
assertMsg(fragmentShader, "fragment shader loaded");
|
||||
|
||||
var program = gl.createProgram();
|
||||
shouldBeTrue("program != null");
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.attachShader(program, vertexShader)");
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.attachShader(program, fragmentShader)");
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.linkProgram(program)");
|
||||
@ -56,13 +57,18 @@ debug("");
|
||||
debug("texture deletion");
|
||||
|
||||
var fbo = gl.createFramebuffer(), fbo2 = gl.createFramebuffer(), fbo3 = gl.createFramebuffer();
|
||||
shouldBeTrue("fbo != null");
|
||||
shouldBeTrue("fbo2 != null");
|
||||
shouldBeTrue("fbo3 != null");
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindFramebuffer(gl.FRAMEBUFFER, fbo)");
|
||||
|
||||
var tex = gl.createTexture();
|
||||
shouldBeTrue("tex != null");
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindTexture(gl.TEXTURE_2D, tex)");
|
||||
shouldBe("gl.getParameter(gl.TEXTURE_BINDING_2D)", "tex");
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex, 0)");
|
||||
shouldBe("gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME)", "tex");
|
||||
shouldBe("gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE)", "gl.TEXTURE");
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.deleteTexture(tex)");
|
||||
// Deleting a texture bound to the currently-bound fbo is the same as
|
||||
// detaching the textue from fbo first, then delete the texture.
|
||||
@ -74,6 +80,7 @@ shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindTexture(gl.TEXTURE_2D, tex)");
|
||||
shouldBeNull("gl.getParameter(gl.TEXTURE_BINDING_2D)");
|
||||
|
||||
var texCubeMap = gl.createTexture();
|
||||
shouldBeTrue("texCubeMap != null");
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindTexture(gl.TEXTURE_CUBE_MAP, texCubeMap)");
|
||||
shouldBe("gl.getParameter(gl.TEXTURE_BINDING_CUBE_MAP)", "texCubeMap");
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.deleteTexture(texCubeMap)");
|
||||
@ -83,16 +90,33 @@ shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindTexture(gl.TEXTURE_CUBE_MAP, texC
|
||||
shouldBeNull("gl.getParameter(gl.TEXTURE_BINDING_CUBE_MAP)");
|
||||
|
||||
var t = gl.createTexture();
|
||||
shouldBeTrue("t != null");
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindTexture(gl.TEXTURE_2D, t)");
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE)");
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.deleteTexture(t)");
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindTexture(gl.TEXTURE_2D, t)");
|
||||
shouldGenerateGLError(gl, gl.INVALID_OPERATION, "gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE)");
|
||||
|
||||
var t2 = gl.createTexture();
|
||||
shouldBeTrue("t2 != null");
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.activeTexture(gl.TEXTURE0)");
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindTexture(gl.TEXTURE_2D, t2)");
|
||||
shouldBe("gl.getParameter(gl.TEXTURE_BINDING_2D)", "t2");
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.activeTexture(gl.TEXTURE1)");
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindTexture(gl.TEXTURE_2D, t2)");
|
||||
shouldBe("gl.getParameter(gl.TEXTURE_BINDING_2D)", "t2");
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.deleteTexture(t2)");
|
||||
shouldBeNull("gl.getParameter(gl.TEXTURE_BINDING_2D)");
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.activeTexture(gl.TEXTURE0)");
|
||||
shouldBeNull("gl.getParameter(gl.TEXTURE_BINDING_2D)");
|
||||
|
||||
debug("");
|
||||
debug("renderbuffer deletion");
|
||||
|
||||
var rbo = gl.createRenderbuffer(), rbo2 = gl.createRenderbuffer(), rbo3 = gl.createRenderbuffer();
|
||||
shouldBeTrue("rbo != null");
|
||||
shouldBeTrue("rbo2 != null");
|
||||
shouldBeTrue("rbo3 != null");
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindRenderbuffer(gl.RENDERBUFFER, rbo)");
|
||||
shouldBe("gl.getParameter(gl.RENDERBUFFER_BINDING)", "rbo");
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, rbo)");
|
||||
@ -111,10 +135,179 @@ shouldBe("gl.getParameter(gl.RENDERBUFFER_BINDING)", "rbo2");
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.deleteRenderbuffer(rbo3)");
|
||||
shouldBe("gl.getParameter(gl.RENDERBUFFER_BINDING)", "rbo2");
|
||||
|
||||
debug("");
|
||||
debug("using deleted renderbuffer");
|
||||
rbo = gl.createRenderbuffer();
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindRenderbuffer(gl.RENDERBUFFER, rbo)");
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA4, 16, 16)");
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindFramebuffer(gl.FRAMEBUFFER, fbo)");
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, rbo)");
|
||||
if (gl.checkFramebufferStatus(gl.FRAMEBUFFER) == gl.FRAMEBUFFER_COMPLETE) {
|
||||
// make backbuffer red
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindFramebuffer(gl.FRAMEBUFFER, null)");
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.clearColor(1,0,0,1)");
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.clear(gl.COLOR_BUFFER_BIT)");
|
||||
// make fbo green
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindFramebuffer(gl.FRAMEBUFFER, fbo)");
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.clearColor(0,1,0,1)");
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.clear(gl.COLOR_BUFFER_BIT)");
|
||||
// Bind backbuffer.
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindFramebuffer(gl.FRAMEBUFFER, null)");
|
||||
// delete renderbuffer. It should still be attached to fbo though.
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.deleteRenderbuffer(rbo)");
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, 'wtu.checkCanvasRect(gl, 0, 0, 16, 16, [255,0,0,255], "backbuffer should be red")');
|
||||
// Use fbo that has deleted rbo.
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindFramebuffer(gl.FRAMEBUFFER, fbo)");
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, 'wtu.checkCanvasRect(gl, 0, 0, 16, 16, [0,255,0,255], "fbo should be green")');
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.clearColor(0,0,1,1)");
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.clear(gl.COLOR_BUFFER_BIT)");
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, 'wtu.checkCanvasRect(gl, 0, 0, 16, 16, [0,0,255,255], "fbo should be blue")');
|
||||
// Bind backbuffer.
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindFramebuffer(gl.FRAMEBUFFER, null)");
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, 'wtu.checkCanvasRect(gl, 0, 0, 16, 16, [255,0,0,255], "backbuffer should be red")');
|
||||
}
|
||||
|
||||
debug("");
|
||||
debug("renderbuffer attached twice to same framebuffer");
|
||||
rbo = gl.createRenderbuffer();
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindRenderbuffer(gl.RENDERBUFFER, rbo)");
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA4, 16, 16)");
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindFramebuffer(gl.FRAMEBUFFER, fbo)");
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, rbo)");
|
||||
if (gl.checkFramebufferStatus(gl.FRAMEBUFFER) == gl.FRAMEBUFFER_COMPLETE) {
|
||||
var rbo2 = gl.createRenderbuffer();
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindRenderbuffer(gl.RENDERBUFFER, rbo2)");
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA4, 16, 16)");
|
||||
// attach rbo2 at two attachment points incompatible with it
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, rbo2)");
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.STENCIL_ATTACHMENT, gl.RENDERBUFFER, rbo2)");
|
||||
shouldBeTrue("gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME) == rbo2");
|
||||
shouldBeTrue("gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.STENCIL_ATTACHMENT, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME) == rbo2");
|
||||
// fbo can't be complete as rbo2 is attached at incompatible attachment points
|
||||
shouldBeFalse("gl.checkFramebufferStatus(gl.FRAMEBUFFER) == gl.FRAMEBUFFER_COMPLETE");
|
||||
// now we delete rbo2, which detaches it from the two attachment points where it currently is attached
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.deleteRenderbuffer(rbo2)");
|
||||
shouldBe("gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE)", "gl.NONE");
|
||||
shouldBe("gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.STENCIL_ATTACHMENT, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE)", "gl.NONE");
|
||||
// we should now be in the same state as before with only rbo attached, so fbo should be complete again
|
||||
shouldBe("gl.checkFramebufferStatus(gl.FRAMEBUFFER)", "gl.FRAMEBUFFER_COMPLETE");
|
||||
shouldBeTrue("gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME) == rbo");
|
||||
}
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.deleteRenderbuffer(rbo)");
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindFramebuffer(gl.FRAMEBUFFER, null)");
|
||||
|
||||
|
||||
|
||||
debug("");
|
||||
debug("using deleted texture");
|
||||
tex = gl.createTexture();
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindTexture(gl.TEXTURE_2D, tex)");
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindFramebuffer(gl.FRAMEBUFFER, fbo)");
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex, 0)");
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, null)");
|
||||
if (gl.checkFramebufferStatus(gl.FRAMEBUFFER) == gl.FRAMEBUFFER_COMPLETE) {
|
||||
// make fbo green
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindFramebuffer(gl.FRAMEBUFFER, fbo)");
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.clearColor(0,1,0,1)");
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.clear(gl.COLOR_BUFFER_BIT)");
|
||||
// Bind backbuffer.
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindFramebuffer(gl.FRAMEBUFFER, null)");
|
||||
// delete texture. It should still be attached to fbo though.
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.deleteTexture(tex)");
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, 'wtu.checkCanvasRect(gl, 0, 0, 1, 1, [255,0,0,255], "backbuffer should be red")');
|
||||
// Use fbo that has deleted texture.
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindFramebuffer(gl.FRAMEBUFFER, fbo)");
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, 'wtu.checkCanvasRect(gl, 0, 0, 1, 1, [0,255,0,255], "fbo should be green")');
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.clearColor(0,0,1,1)");
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.clear(gl.COLOR_BUFFER_BIT)");
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, 'wtu.checkCanvasRect(gl, 0, 0, 1, 1, [0,0,255,255], "fbo should be blue")');
|
||||
// Bind backbuffer.
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindFramebuffer(gl.FRAMEBUFFER, null)");
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, 'wtu.checkCanvasRect(gl, 0, 0, 16, 16, [255,0,0,255], "backbuffer should be red")');
|
||||
}
|
||||
|
||||
debug("");
|
||||
debug("using deleted renderbuffer");
|
||||
rbo = gl.createRenderbuffer();
|
||||
shouldBeTrue("rbo != null");
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindRenderbuffer(gl.RENDERBUFFER, rbo)");
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA4, 16, 16)");
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindFramebuffer(gl.FRAMEBUFFER, fbo)");
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, rbo)");
|
||||
if (gl.checkFramebufferStatus(gl.FRAMEBUFFER) == gl.FRAMEBUFFER_COMPLETE) {
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindFramebuffer(gl.FRAMEBUFFER, fbo2)");
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, rbo)");
|
||||
shouldBe("gl.checkFramebufferStatus(gl.FRAMEBUFFER)", "gl.FRAMEBUFFER_COMPLETE");
|
||||
// make backbuffer red
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindFramebuffer(gl.FRAMEBUFFER, null)");
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.clearColor(1,0,0,1)");
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.clear(gl.COLOR_BUFFER_BIT)");
|
||||
// make fbo green
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindFramebuffer(gl.FRAMEBUFFER, fbo)");
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.clearColor(0,1,0,1)");
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.clear(gl.COLOR_BUFFER_BIT)");
|
||||
// delete renderbuffer. It should still be attached to fbo2 though.
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.deleteRenderbuffer(rbo)");
|
||||
// fbo has no attachments
|
||||
shouldBeTrue("gl.checkFramebufferStatus(gl.FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE");
|
||||
// Use fbo2 that has deleted rbo.
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindFramebuffer(gl.FRAMEBUFFER, fbo2)");
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, 'wtu.checkCanvasRect(gl, 0, 0, 16, 16, [0,255,0,255], "fbo should be green")');
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.clearColor(0,0,1,1)");
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.clear(gl.COLOR_BUFFER_BIT)");
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, 'wtu.checkCanvasRect(gl, 0, 0, 16, 16, [0,0,255,255], "fbo should be blue")');
|
||||
shouldBeTrue("gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME) == rbo");
|
||||
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindFramebuffer(gl.FRAMEBUFFER, fbo)");
|
||||
shouldGenerateGLError(gl, gl.INVALID_ENUM, "gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME)");
|
||||
shouldGenerateGLError(gl, gl.NONE, "gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE)");
|
||||
shouldBeTrue("gl.checkFramebufferStatus(gl.FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE");
|
||||
// Bind backbuffer.
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindFramebuffer(gl.FRAMEBUFFER, null)");
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, 'wtu.checkCanvasRect(gl, 0, 0, 16, 16, [255,0,0,255], "backbuffer should be red")');
|
||||
}
|
||||
|
||||
debug("");
|
||||
debug("using deleted texture");
|
||||
tex = gl.createTexture();
|
||||
shouldBeTrue("tex != null");
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindTexture(gl.TEXTURE_2D, tex)");
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindFramebuffer(gl.FRAMEBUFFER, fbo)");
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex, 0)");
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, null)");
|
||||
if (gl.checkFramebufferStatus(gl.FRAMEBUFFER) == gl.FRAMEBUFFER_COMPLETE) {
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindFramebuffer(gl.FRAMEBUFFER, fbo2)");
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex, 0)");
|
||||
// make fbo green
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindFramebuffer(gl.FRAMEBUFFER, fbo)");
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.clearColor(0,1,0,1)");
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.clear(gl.COLOR_BUFFER_BIT)");
|
||||
// delete texture. It should still be attached to fbo2 though.
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.deleteTexture(tex)");
|
||||
// fbo has no attachments
|
||||
shouldBeTrue("gl.checkFramebufferStatus(gl.FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE");
|
||||
// Use fbo that has deleted texture.
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindFramebuffer(gl.FRAMEBUFFER, fbo2)");
|
||||
shouldBeTrue("gl.checkFramebufferStatus(gl.FRAMEBUFFER) == gl.FRAMEBUFFER_COMPLETE");
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, 'wtu.checkCanvasRect(gl, 0, 0, 1, 1, [0,255,0,255], "fbo should be green")');
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.clearColor(0,0,1,1)");
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.clear(gl.COLOR_BUFFER_BIT)");
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, 'wtu.checkCanvasRect(gl, 0, 0, 1, 1, [0,0,255,255], "fbo should be blue")');
|
||||
shouldBeTrue("gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME) == tex");
|
||||
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindFramebuffer(gl.FRAMEBUFFER, fbo)");
|
||||
shouldGenerateGLError(gl, gl.INVALID_ENUM, "gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME)");
|
||||
shouldBeTrue("gl.checkFramebufferStatus(gl.FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE");
|
||||
// Bind backbuffer.
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindFramebuffer(gl.FRAMEBUFFER, null)");
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, 'wtu.checkCanvasRect(gl, 0, 0, 16, 16, [255,0,0,255], "backbuffer should be red")');
|
||||
}
|
||||
|
||||
debug("");
|
||||
debug("buffer deletion");
|
||||
|
||||
var buffer = gl.createBuffer();
|
||||
shouldBeTrue("buffer != null");
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindBuffer(gl.ARRAY_BUFFER, buffer)");
|
||||
shouldBe("gl.getParameter(gl.ARRAY_BUFFER_BINDING)", "buffer");
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.deleteBuffer(buffer)");
|
||||
@ -123,7 +316,19 @@ shouldBeNull("gl.getParameter(gl.ARRAY_BUFFER_BINDING)");
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindBuffer(gl.ARRAY_BUFFER, buffer)");
|
||||
shouldBeNull("gl.getParameter(gl.ARRAY_BUFFER_BINDING)");
|
||||
|
||||
var buffer2 = gl.createBuffer();
|
||||
shouldBeTrue("buffer2 != null");
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindBuffer(gl.ARRAY_BUFFER, buffer2)");
|
||||
shouldBe("gl.getParameter(gl.ARRAY_BUFFER_BINDING)", "buffer2");
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindBuffer(gl.ARRAY_BUFFER, null)");
|
||||
shouldBeNull("gl.getParameter(gl.ARRAY_BUFFER_BINDING)");
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.deleteBuffer(buffer2)");
|
||||
shouldBeFalse("gl.isBuffer(buffer2)");
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindBuffer(gl.ARRAY_BUFFER, buffer2)");
|
||||
shouldBeNull("gl.getParameter(gl.ARRAY_BUFFER_BINDING)");
|
||||
|
||||
var bufferElement = gl.createBuffer();
|
||||
shouldBeTrue("bufferElement != null");
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, bufferElement)");
|
||||
shouldBe("gl.getParameter(gl.ELEMENT_ARRAY_BUFFER_BINDING)", "bufferElement");
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.deleteBuffer(bufferElement)");
|
||||
@ -133,12 +338,35 @@ shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, b
|
||||
shouldBeNull("gl.getParameter(gl.ELEMENT_ARRAY_BUFFER_BINDING)");
|
||||
|
||||
var b = gl.createBuffer();
|
||||
shouldBeTrue("b != null");
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindBuffer(gl.ARRAY_BUFFER, b)");
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bufferData(gl.ARRAY_BUFFER, 1, gl.STATIC_DRAW)");
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.deleteBuffer(b)");
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindBuffer(gl.ARRAY_BUFFER, b)");
|
||||
shouldGenerateGLError(gl, gl.INVALID_OPERATION, "gl.bufferData(gl.ARRAY_BUFFER, 1, gl.STATIC_DRAW)");
|
||||
|
||||
var b1 = gl.createBuffer();
|
||||
shouldBeTrue("b1 != null");
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindBuffer(gl.ARRAY_BUFFER, b1);");
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.enableVertexAttribArray(1);");
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.vertexAttribPointer(1, 4, gl.FLOAT, false, 0, 0);");
|
||||
var b2 = gl.createBuffer();
|
||||
shouldBeTrue("b2 != null");
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindBuffer(gl.ARRAY_BUFFER, b2);");
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.enableVertexAttribArray(2);");
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.vertexAttribPointer(2, 4, gl.FLOAT, false, 0, 0);");
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.enableVertexAttribArray(3);");
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.vertexAttribPointer(3, 4, gl.FLOAT, false, 0, 0);");
|
||||
shouldBe("gl.getVertexAttrib(1, gl.VERTEX_ATTRIB_ARRAY_BUFFER_BINDING)", "b1");
|
||||
shouldBe("gl.getVertexAttrib(2, gl.VERTEX_ATTRIB_ARRAY_BUFFER_BINDING)", "b2");
|
||||
shouldBe("gl.getVertexAttrib(3, gl.VERTEX_ATTRIB_ARRAY_BUFFER_BINDING)", "b2");
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.deleteBuffer(b2);");
|
||||
shouldBe("gl.getVertexAttrib(1, gl.VERTEX_ATTRIB_ARRAY_BUFFER_BINDING)", "b1");
|
||||
shouldBeNull("gl.getVertexAttrib(2, gl.VERTEX_ATTRIB_ARRAY_BUFFER_BINDING)");
|
||||
shouldBeNull("gl.getVertexAttrib(3, gl.VERTEX_ATTRIB_ARRAY_BUFFER_BINDING)");
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.deleteBuffer(b1);");
|
||||
shouldBeNull("gl.getVertexAttrib(1, gl.VERTEX_ATTRIB_ARRAY_BUFFER_BINDING)");
|
||||
|
||||
debug("");
|
||||
debug("framebuffer deletion");
|
||||
|
||||
@ -154,6 +382,41 @@ shouldBe("gl.getParameter(gl.FRAMEBUFFER_BINDING)", "fbo2");
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.deleteFramebuffer(fbo3)");
|
||||
shouldBe("gl.getParameter(gl.FRAMEBUFFER_BINDING)", "fbo2");
|
||||
|
||||
fbo = gl.createFramebuffer();
|
||||
rbo = gl.createRenderbuffer();
|
||||
shouldBeTrue("fbo != null");
|
||||
shouldBeTrue("rbo != null");
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindFramebuffer(gl.FRAMEBUFFER, fbo)");
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindRenderbuffer(gl.RENDERBUFFER, rbo)");
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA4, 16, 16)");
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, rbo)");
|
||||
if (gl.checkFramebufferStatus(gl.FRAMEBUFFER) == gl.FRAMEBUFFER_COMPLETE) {
|
||||
// set backbuffer to red
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindFramebuffer(gl.FRAMEBUFFER, null)");
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.clearColor(1,0,0,1)");
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.clear(gl.COLOR_BUFFER_BIT)");
|
||||
// set framebuffer to green
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindFramebuffer(gl.FRAMEBUFFER, fbo)");
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.clearColor(0,1,0,1)");
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.clear(gl.COLOR_BUFFER_BIT)");
|
||||
// check framebuffer
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, 'wtu.checkCanvasRect(gl, 0, 0, 16, 16, [0,255,0,255], "fbo should be green")');
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, 'wtu.checkCanvasRect(gl, 16, 16, 1, 1, [0,0,0,0], "outside fbo should be black")');
|
||||
// delete framebuffer. because this was the bound fbo the backbuffer should be active now
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.deleteFramebuffer(fbo)");
|
||||
// check backbuffer
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, 'wtu.checkCanvasRect(gl, 0, 0, 300, 150, [255,0,0,255], "backbuffer should be red")');
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, 'wtu.checkCanvasRect(gl, 300, 0, 300, 300, [0,0,0,0], "outside backbuffer should be black")');
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, 'wtu.checkCanvasRect(gl, 0, 150, 300, 300, [0,0,0,0], "outside backbuffer should be black")');
|
||||
// check drawing to backbuffer
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.clearColor(0,1,0,1)");
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.clear(gl.COLOR_BUFFER_BIT)");
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, 'wtu.checkCanvasRect(gl, 0, 0, 300, 150, [0,255,0,255], "fbo should be green")');
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindFramebuffer(gl.FRAMEBUFFER, null)");
|
||||
// check again because many buggy implementations will have bound to the true backbuffer on deleteFramebuffer.
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, 'wtu.checkCanvasRect(gl, 0, 0, 300, 150, [0,255,0,255], "fbo should be green")');
|
||||
}
|
||||
|
||||
successfullyParsed = true;
|
||||
</script>
|
||||
|
||||
|
@ -59,7 +59,7 @@ uniform vec4 foo;
|
||||
varying vec4 texCoord0;
|
||||
void main()
|
||||
{
|
||||
gl_FragColor = vec4(foo.r/256.0, foo.g/256.0, foo.b/256.0, foo.a*texCoord0.z/256.0);
|
||||
gl_FragColor = vec4(foo.r/255.0, foo.g/255.0, foo.b/255.0, foo.a*texCoord0.z/255.0);
|
||||
}
|
||||
</script>
|
||||
<style>canvas{ position:absolute; }</style>
|
||||
|
@ -82,10 +82,10 @@ varying vec4 texCoord0;
|
||||
void main()
|
||||
{
|
||||
gl_FragColor = vec4(
|
||||
uniV4[0].r/256.0,
|
||||
uniV4[0].g/256.0,
|
||||
uniV4[0].b/256.0,
|
||||
uniV4[0].a*texCoord0.z/256.0);
|
||||
uniV4[0].r/255.0,
|
||||
uniV4[0].g/255.0,
|
||||
uniV4[0].b/255.0,
|
||||
uniV4[0].a*texCoord0.z/255.0);
|
||||
}
|
||||
</script>
|
||||
<style>canvas{ position:absolute; }</style>
|
||||
|
@ -87,10 +87,10 @@ varying vec4 texCoord0;
|
||||
void main()
|
||||
{
|
||||
gl_FragColor = vec4(
|
||||
uniV4.r/256.0,
|
||||
uniV4.g/256.0,
|
||||
uniV4.b/256.0,
|
||||
uniV4.a*texCoord0.z/256.0);
|
||||
uniV4.r/255.0,
|
||||
uniV4.g/255.0,
|
||||
uniV4.b/255.0,
|
||||
uniV4.a*texCoord0.z/255.0);
|
||||
}
|
||||
</script>
|
||||
<style>canvas{ position:absolute; }</style>
|
||||
|
@ -27,29 +27,43 @@ var colorBuffer;
|
||||
var width;
|
||||
var height;
|
||||
|
||||
function testAttachment(attachment, buffer, isConflicted)
|
||||
const ALLOW_COMPLETE = 0x01;
|
||||
const ALLOW_UNSUPPORTED = 0x02;
|
||||
const ALLOW_INCOMPLETE_ATTACHMENT = 0x04;
|
||||
|
||||
function CheckFramebufferForAllowedStatuses(allowedStatuses)
|
||||
{
|
||||
// If the framebuffer is in an error state for multiple reasons,
|
||||
// we can't guarantee which one will be reported.
|
||||
var status = gl.checkFramebufferStatus(gl.FRAMEBUFFER);
|
||||
var statusAllowed = ((allowedStatuses & ALLOW_COMPLETE) && (status == gl.FRAMEBUFFER_COMPLETE)) ||
|
||||
((allowedStatuses & ALLOW_UNSUPPORTED) && (status == gl.FRAMEBUFFER_UNSUPPORTED)) ||
|
||||
((allowedStatuses & ALLOW_INCOMPLETE_ATTACHMENT) && (status == gl.FRAMEBUFFER_INCOMPLETE_ATTACHMENT));
|
||||
var msg = "gl.checkFramebufferStatus(gl.FRAMEBUFFER) returned " + status;
|
||||
if (statusAllowed)
|
||||
testPassed(msg);
|
||||
else
|
||||
testFailed(msg);
|
||||
}
|
||||
|
||||
function testAttachment(attachment, buffer, allowedStatuses)
|
||||
{
|
||||
shouldBeNonNull("fbo = gl.createFramebuffer()");
|
||||
gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
|
||||
gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, colorBuffer);
|
||||
gl.framebufferRenderbuffer(gl.FRAMEBUFFER, attachment, gl.RENDERBUFFER, buffer);
|
||||
glErrorShouldBe(gl, gl.NO_ERROR);
|
||||
// If the framebuffer is in an error state for multiple reasons,
|
||||
// we can't guarantee which one will be reported.
|
||||
if ((width == 0 || height == 0) && !isConflicted) {
|
||||
// Zero-sized renderbuffers are supposed to result in an incomplete attachment.
|
||||
// However, certain combination may violate implementation specific restrictions.
|
||||
shouldBeTrue("gl.checkFramebufferStatus(gl.FRAMEBUFFER) == gl.FRAMEBUFFER_INCOMPLETE_ATTACHMENT || gl.checkFramebufferStatus(gl.FRAMEBUFFER) == gl.FRAMEBUFFER_UNSUPPORTED");
|
||||
} else if (isConflicted) {
|
||||
shouldBe("gl.checkFramebufferStatus(gl.FRAMEBUFFER)", "gl.FRAMEBUFFER_UNSUPPORTED");
|
||||
CheckFramebufferForAllowedStatuses(allowedStatuses);
|
||||
if ((allowedStatuses & ALLOW_COMPLETE) == 0) {
|
||||
gl.clear(gl.COLOR_BUFFER_BIT);
|
||||
glErrorShouldBe(gl, gl.INVALID_FRAMEBUFFER_OPERATION);
|
||||
gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, new Uint8Array(width * height * 4));
|
||||
glErrorShouldBe(gl, gl.INVALID_FRAMEBUFFER_OPERATION);
|
||||
}
|
||||
gl.deleteFramebuffer(fbo);
|
||||
}
|
||||
|
||||
function testAttachments(attachment0, buffer0, attachment1, buffer1, isConflicted)
|
||||
function testAttachments(attachment0, buffer0, attachment1, buffer1, allowedStatuses)
|
||||
{
|
||||
shouldBeNonNull("fbo = gl.createFramebuffer()");
|
||||
gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
|
||||
@ -58,27 +72,20 @@ function testAttachments(attachment0, buffer0, attachment1, buffer1, isConflicte
|
||||
glErrorShouldBe(gl, gl.NO_ERROR);
|
||||
gl.framebufferRenderbuffer(gl.FRAMEBUFFER, attachment1, gl.RENDERBUFFER, buffer1);
|
||||
glErrorShouldBe(gl, gl.NO_ERROR);
|
||||
// If the framebuffer is in an error state for multiple reasons,
|
||||
// we can't guarantee which one will be reported.
|
||||
if ((width == 0 || height == 0) && !isConflicted) {
|
||||
// Zero-sized renderbuffers are supposed to result in an incomplete attachment.
|
||||
// However, certain combination may violate implementation specific restrictions.
|
||||
shouldBeTrue("gl.checkFramebufferStatus(gl.FRAMEBUFFER) == gl.FRAMEBUFFER_INCOMPLETE_ATTACHMENT || gl.checkFramebufferStatus(gl.FRAMEBUFFER) == gl.FRAMEBUFFER_UNSUPPORTED");
|
||||
} else if (isConflicted) {
|
||||
shouldBe("gl.checkFramebufferStatus(gl.FRAMEBUFFER)", "gl.FRAMEBUFFER_UNSUPPORTED");
|
||||
}
|
||||
CheckFramebufferForAllowedStatuses(allowedStatuses);
|
||||
gl.deleteFramebuffer(fbo);
|
||||
}
|
||||
|
||||
function testColorRenderbuffer(internalformat)
|
||||
function testColorRenderbuffer(internalformat, allowedStatuses)
|
||||
{
|
||||
shouldBeNonNull("colorBuffer = gl.createRenderbuffer()");
|
||||
gl.bindRenderbuffer(gl.RENDERBUFFER, colorBuffer);
|
||||
gl.renderbufferStorage(gl.RENDERBUFFER, internalformat, width, height);
|
||||
glErrorShouldBe(gl, gl.NO_ERROR);
|
||||
testAttachment(gl.COLOR_ATTACHMENT0, colorBuffer, false);
|
||||
testAttachment(gl.COLOR_ATTACHMENT0, colorBuffer, allowedStatuses);
|
||||
}
|
||||
|
||||
function testDepthStencilRenderbuffer()
|
||||
function testDepthStencilRenderbuffer(allowedStatuses)
|
||||
{
|
||||
shouldBeNonNull("depthStencilBuffer = gl.createRenderbuffer()");
|
||||
gl.bindRenderbuffer(gl.RENDERBUFFER, depthStencilBuffer);
|
||||
@ -103,7 +110,7 @@ function testDepthStencilRenderbuffer()
|
||||
shouldBeTrue("gl.getRenderbufferParameter(gl.RENDERBUFFER, gl.RENDERBUFFER_STENCIL_SIZE) > 0");
|
||||
}
|
||||
glErrorShouldBe(gl, gl.NO_ERROR);
|
||||
testAttachment(gl.DEPTH_STENCIL_ATTACHMENT, depthStencilBuffer, false);
|
||||
testAttachment(gl.DEPTH_STENCIL_ATTACHMENT, depthStencilBuffer, allowedStatuses);
|
||||
}
|
||||
|
||||
description("Test framebuffer object attachment behaviors");
|
||||
@ -134,49 +141,59 @@ for (width = 0; width <= 2; width += 2)
|
||||
gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_STENCIL, width, height);
|
||||
glErrorShouldBe(gl, gl.NO_ERROR);
|
||||
|
||||
var allowedStatusForGoodCase
|
||||
= (width == 0 || height == 0) ? ALLOW_INCOMPLETE_ATTACHMENT : ALLOW_COMPLETE;
|
||||
|
||||
// some cases involving stencil seem to be implementation-dependent
|
||||
var allowedStatusForImplDependentCase = allowedStatusForGoodCase | ALLOW_UNSUPPORTED;
|
||||
|
||||
debug("Attach depth using DEPTH_ATTACHMENT");
|
||||
testAttachment(gl.DEPTH_ATTACHMENT, depthBuffer, false);
|
||||
testAttachment(gl.DEPTH_ATTACHMENT, depthBuffer, allowedStatusForGoodCase);
|
||||
debug("Attach depth using STENCIL_ATTACHMENT");
|
||||
testAttachment(gl.STENCIL_ATTACHMENT, depthBuffer, true);
|
||||
testAttachment(gl.STENCIL_ATTACHMENT, depthBuffer, ALLOW_INCOMPLETE_ATTACHMENT);
|
||||
debug("Attach depth using DEPTH_STENCIL_ATTACHMENT");
|
||||
testAttachment(gl.DEPTH_STENCIL_ATTACHMENT, depthBuffer, true);
|
||||
testAttachment(gl.DEPTH_STENCIL_ATTACHMENT, depthBuffer, ALLOW_INCOMPLETE_ATTACHMENT);
|
||||
debug("Attach stencil using STENCIL_ATTACHMENT");
|
||||
testAttachment(gl.STENCIL_ATTACHMENT, stencilBuffer, false);
|
||||
testAttachment(gl.STENCIL_ATTACHMENT, stencilBuffer, allowedStatusForImplDependentCase);
|
||||
debug("Attach stencil using DEPTH_ATTACHMENT");
|
||||
testAttachment(gl.DEPTH_ATTACHMENT, stencilBuffer, true);
|
||||
testAttachment(gl.DEPTH_ATTACHMENT, stencilBuffer, ALLOW_INCOMPLETE_ATTACHMENT);
|
||||
debug("Attach stencil using DEPTH_STENCIL_ATTACHMENT");
|
||||
testAttachment(gl.DEPTH_STENCIL_ATTACHMENT, stencilBuffer, true);
|
||||
testAttachment(gl.DEPTH_STENCIL_ATTACHMENT, stencilBuffer, ALLOW_INCOMPLETE_ATTACHMENT);
|
||||
debug("Attach depthStencil using DEPTH_STENCIL_ATTACHMENT");
|
||||
testAttachment(gl.DEPTH_STENCIL_ATTACHMENT, depthStencilBuffer, false);
|
||||
testAttachment(gl.DEPTH_STENCIL_ATTACHMENT, depthStencilBuffer, allowedStatusForGoodCase);
|
||||
debug("Attach depthStencil using DEPTH_ATTACHMENT");
|
||||
testAttachment(gl.DEPTH_ATTACHMENT, depthStencilBuffer, true);
|
||||
testAttachment(gl.DEPTH_ATTACHMENT, depthStencilBuffer, ALLOW_INCOMPLETE_ATTACHMENT);
|
||||
debug("Attach depthStencil using STENCIL_ATTACHMENT");
|
||||
testAttachment(gl.STENCIL_ATTACHMENT, depthStencilBuffer, true);
|
||||
testAttachment(gl.STENCIL_ATTACHMENT, depthStencilBuffer, ALLOW_INCOMPLETE_ATTACHMENT);
|
||||
|
||||
var allowedStatusForConflictedAttachment
|
||||
= (width == 0 || height == 0) ? ALLOW_UNSUPPORTED | ALLOW_INCOMPLETE_ATTACHMENT
|
||||
: ALLOW_UNSUPPORTED;
|
||||
|
||||
debug("Attach depth, then stencil, causing conflict");
|
||||
testAttachments(gl.DEPTH_ATTACHMENT, depthBuffer, gl.STENCIL_ATTACHMENT, stencilBuffer, true);
|
||||
testAttachments(gl.DEPTH_ATTACHMENT, depthBuffer, gl.STENCIL_ATTACHMENT, stencilBuffer, allowedStatusForConflictedAttachment);
|
||||
debug("Attach stencil, then depth, causing conflict");
|
||||
testAttachments(gl.STENCIL_ATTACHMENT, stencilBuffer, gl.DEPTH_ATTACHMENT, depthBuffer, true);
|
||||
testAttachments(gl.STENCIL_ATTACHMENT, stencilBuffer, gl.DEPTH_ATTACHMENT, depthBuffer, allowedStatusForConflictedAttachment);
|
||||
debug("Attach depth, then depthStencil, causing conflict");
|
||||
testAttachments(gl.DEPTH_ATTACHMENT, depthBuffer, gl.DEPTH_STENCIL_ATTACHMENT, depthStencilBuffer, true);
|
||||
testAttachments(gl.DEPTH_ATTACHMENT, depthBuffer, gl.DEPTH_STENCIL_ATTACHMENT, depthStencilBuffer, allowedStatusForConflictedAttachment);
|
||||
debug("Attach depthStencil, then depth, causing conflict");
|
||||
testAttachments(gl.DEPTH_STENCIL_ATTACHMENT, depthStencilBuffer, gl.DEPTH_ATTACHMENT, depthBuffer, true);
|
||||
testAttachments(gl.DEPTH_STENCIL_ATTACHMENT, depthStencilBuffer, gl.DEPTH_ATTACHMENT, depthBuffer, allowedStatusForConflictedAttachment);
|
||||
debug("Attach stencil, then depthStencil, causing conflict");
|
||||
testAttachments(gl.DEPTH_ATTACHMENT, depthBuffer, gl.DEPTH_STENCIL_ATTACHMENT, depthStencilBuffer, true);
|
||||
testAttachments(gl.DEPTH_ATTACHMENT, depthBuffer, gl.DEPTH_STENCIL_ATTACHMENT, depthStencilBuffer, allowedStatusForConflictedAttachment);
|
||||
debug("Attach depthStencil, then stencil, causing conflict");
|
||||
testAttachments(gl.DEPTH_STENCIL_ATTACHMENT, depthStencilBuffer, gl.STENCIL_ATTACHMENT, stencilBuffer, true);
|
||||
testAttachments(gl.DEPTH_STENCIL_ATTACHMENT, depthStencilBuffer, gl.STENCIL_ATTACHMENT, stencilBuffer, allowedStatusForConflictedAttachment);
|
||||
|
||||
debug("Attach color renderbuffer with internalformat == RGBA4");
|
||||
testColorRenderbuffer(gl.RGBA4);
|
||||
testColorRenderbuffer(gl.RGBA4, allowedStatusForGoodCase);
|
||||
|
||||
debug("Attach color renderbuffer with internalformat == RGB5_A1");
|
||||
testColorRenderbuffer(gl.RGB5_A1);
|
||||
testColorRenderbuffer(gl.RGB5_A1, allowedStatusForGoodCase);
|
||||
|
||||
debug("Attach color renderbuffer with internalformat == RGB565");
|
||||
testColorRenderbuffer(gl.RGB565);
|
||||
testColorRenderbuffer(gl.RGB565, allowedStatusForGoodCase);
|
||||
|
||||
debug("Create and attach depthStencil renderbuffer");
|
||||
testDepthStencilRenderbuffer();
|
||||
testDepthStencilRenderbuffer(allowedStatusForGoodCase);
|
||||
}
|
||||
}
|
||||
|
||||
@ -266,23 +283,35 @@ function testUsingIncompleteFramebuffer() {
|
||||
debug("Drawing or reading from an incomplete framebuffer should generate INVALID_FRAMEBUFFER_OPERATION");
|
||||
testRenderingAndReading();
|
||||
|
||||
shouldBeNonNull("fbo = gl.createFramebuffer()");
|
||||
gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
|
||||
shouldBeNonNull("fbo2 = gl.createFramebuffer()");
|
||||
gl.bindFramebuffer(gl.FRAMEBUFFER, fbo2);
|
||||
CheckFramebuffer(gl.FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT);
|
||||
debug("");
|
||||
debug("Drawing or reading from an incomplete framebuffer should generate INVALID_FRAMEBUFFER_OPERATION");
|
||||
testRenderingAndReading();
|
||||
|
||||
shouldBeNonNull("colorBuffer = gl.createRenderbuffer()");
|
||||
gl.bindRenderbuffer(gl.RENDERBUFFER, colorBuffer);
|
||||
gl.framebufferRenderbuffer(
|
||||
gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, colorBuffer);
|
||||
gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA4, 0, 0);
|
||||
debug("");
|
||||
debug("Drawing or reading from an incomplete framebuffer should generate INVALID_FRAMEBUFFER_OPERATION");
|
||||
testRenderingAndReading();
|
||||
|
||||
function testRenderingAndReading() {
|
||||
glErrorShouldBe(gl, gl.NO_ERROR);
|
||||
wtu.drawQuad(gl);
|
||||
glErrorShouldBe(gl, gl.INVALID_FRAMEBUFFER_OPERATION, "drawArrays with incomplete framebuffer");
|
||||
gl.readPixels(0, 0, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, new Uint8Array(4));
|
||||
glErrorShouldBe(gl, gl.INVALID_FRAMEBUFFER_OPERATION, "readPixels from incomplete framebuffer");
|
||||
// copyTexImage and copyTexSubImage can be either INVALID_FRAMEBUFFER_OPERATION because
|
||||
// the framebuffer is invalid OR INVALID_OPERATION because in the case of no attachments
|
||||
// the framebuffer is not of a compatible type.
|
||||
gl.copyTexSubImage2D(gl.TEXTURE_2D, 0, 0, 0, 0, 0, 1, 1);
|
||||
glErrorShouldBe(gl, gl.INVALID_FRAMEBUFFER_OPERATION, "copyTexImage2D from incomplete framebuffer");
|
||||
glErrorShouldBe(gl, [gl.INVALID_FRAMEBUFFER_OPERATION, gl.INVALID_OPERATION], "copyTexImage2D from incomplete framebuffer");
|
||||
gl.copyTexImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 0, 0, 1, 1, 0);
|
||||
glErrorShouldBe(gl, gl.INVALID_FRAMEBUFFER_OPERATION, "copyTexSubImage2D from incomplete framebuffer");
|
||||
glErrorShouldBe(gl, [gl.INVALID_FRAMEBUFFER_OPERATION, gl.INVALID_OPERATION], "copyTexSubImage2D from incomplete framebuffer");
|
||||
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
|
||||
glErrorShouldBe(gl, gl.INVALID_FRAMEBUFFER_OPERATION, "clear with incomplete framebuffer");
|
||||
}
|
||||
|
@ -6,4 +6,4 @@ gl-scissor-test.html
|
||||
more-than-65536-indices.html
|
||||
point-size.html
|
||||
triangle.html
|
||||
|
||||
line-loop-tri-fan.html
|
||||
|
@ -0,0 +1,238 @@
|
||||
<!--
|
||||
Copyright (C) 2011 Opera Software ASA. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY OPERA SOFTWARE ASA. ''AS IS'' AND ANY
|
||||
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
-->
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<link rel="stylesheet" href="../../resources/js-test-style.css"/>
|
||||
<script src="../../resources/js-test-pre.js"></script>
|
||||
<script src="../resources/webgl-test.js"></script>
|
||||
<script id="vshader" type="x-shader/x-vertex">
|
||||
attribute vec2 pos;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = vec4(pos, 0, 1);
|
||||
}
|
||||
</script>
|
||||
|
||||
<script id="fshader" type="x-shader/x-fragment">
|
||||
precision mediump float;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_FragColor = vec4(0, 1, 0, 1);
|
||||
}
|
||||
</script>
|
||||
|
||||
<script>
|
||||
// Check a single 32-bit RGBA pixel.
|
||||
function checkPixel(buf, index, correct) {
|
||||
for (var i = 0; i < 4; ++i) {
|
||||
if (buf[index + i] != correct[i]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Check the line loop by reading the pixels and making sure just the edge
|
||||
// pixels are green and the rest are black.
|
||||
function checkLineLoop(gl, w) {
|
||||
var buf = new Uint8Array(w * w * 4);
|
||||
gl.readPixels(0, 0, w, w, gl.RGBA, gl.UNSIGNED_BYTE, buf);
|
||||
var green = [0,255,0,255];
|
||||
var black = [0,0,0,255];
|
||||
var isCorrect = true;
|
||||
for (var j = 0; j < w * w * 4; j += 4) {
|
||||
var correct = black;
|
||||
if (j < w * 4 || j > w * (w - 1) * 4 || j % (w * 4) == 0 || j % (w * 4) == (w - 1) * 4) {
|
||||
correct = green;
|
||||
}
|
||||
if (!checkPixel(buf, j, correct)) {
|
||||
isCorrect = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (isCorrect) {
|
||||
testPassed("Line loop was drawn correctly.");
|
||||
} else {
|
||||
testFailed("Line loop was drawn incorrectly.");
|
||||
}
|
||||
}
|
||||
|
||||
// Check the tri fan by reading the pixels and making sure they are all green.
|
||||
function checkTriFan(gl, w) {
|
||||
buf = new Uint8Array(w * w * 4);
|
||||
gl.readPixels(0, 0, w, w, gl.RGBA, gl.UNSIGNED_BYTE, buf);
|
||||
var filled = true;
|
||||
for (var j = 0; j < w * w * 4; j += 4) {
|
||||
if (!checkPixel(buf, j, [0,255,0,255])) {
|
||||
filled = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (filled) {
|
||||
testPassed("Triangle fan was drawn correctly.");
|
||||
} else {
|
||||
testFailed("Triangle fan was drawn incorrectly.");
|
||||
}
|
||||
}
|
||||
|
||||
function runTest()
|
||||
{
|
||||
var gl = initWebGL('testbed', 'vshader', 'fshader', ['pos'], [0, 0, 0, 1], 1, { antialias: false });
|
||||
if (!gl) {
|
||||
testFailed('initWebGL(..) failed');
|
||||
return;
|
||||
}
|
||||
var w = document.getElementById('testbed').width;
|
||||
|
||||
gl.enableVertexAttribArray(0);
|
||||
|
||||
//---------- LINE_LOOP----------
|
||||
var d = 1/w;
|
||||
var vertices = new Float32Array([-1+d, -1+d, 1-d, -1+d, 1-d, 1-d, -1+d, 1-d]);
|
||||
var vertBuf = gl.createBuffer();
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, vertBuf);
|
||||
gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);
|
||||
gl.vertexAttribPointer(0, 2, gl.FLOAT, false, 0, 0);
|
||||
var indBuf = gl.createBuffer();
|
||||
var indices = new Uint16Array([0, 1, 2, 3]);
|
||||
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indBuf);
|
||||
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indices, gl.STATIC_DRAW);
|
||||
|
||||
debug('Draw a square using a line loop and verify that it draws all four sides and nothing else.');
|
||||
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
|
||||
gl.drawArrays(gl.LINE_LOOP, 0, vertices.length / 2);
|
||||
checkLineLoop(gl, w);
|
||||
|
||||
debug('Draw a square using an indexed line loop and verify that it draws all four sides and nothing else.');
|
||||
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
|
||||
gl.drawElements(gl.LINE_LOOP, indices.length, gl.UNSIGNED_SHORT, 0);
|
||||
checkLineLoop(gl, w);
|
||||
|
||||
vertices = new Float32Array([0, 0, 0, 0, 0, 0, -1+d, -1+d, 1-d, -1+d, 1-d, 1-d, -1+d, 1-d]);
|
||||
vertBuf = gl.createBuffer();
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, vertBuf);
|
||||
gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);
|
||||
gl.vertexAttribPointer(0, 2, gl.FLOAT, false, 0, 0);
|
||||
indBuf = gl.createBuffer();
|
||||
indices = new Uint16Array([0, 1, 2, 3, 4, 5, 6]);
|
||||
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indBuf);
|
||||
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indices, gl.STATIC_DRAW);
|
||||
|
||||
debug('Draw a square using a line loop with a vertex buffer offset and verify that it draws all four sides and nothing else.');
|
||||
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
|
||||
gl.drawArrays(gl.LINE_LOOP, 3, vertices.length / 2 - 3);
|
||||
checkLineLoop(gl, w);
|
||||
|
||||
debug('Draw a square using an indexed line loop with an index buffer offset and verify that it draws all four sides and nothing else.');
|
||||
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
|
||||
gl.drawElements(gl.LINE_LOOP, indices.length - 3, gl.UNSIGNED_SHORT, 3 * 2);
|
||||
checkLineLoop(gl, w);
|
||||
|
||||
//---------- LINE_LOOP UBYTE ----------
|
||||
var degenVerts = new Array(252 * 2);
|
||||
for (var j = 0; j < 252 * 2; ++j) {
|
||||
degenVerts[j] = -1+d;
|
||||
}
|
||||
degenVerts = degenVerts.concat([-1+d, -1+d, 1-d, -1+d, 1-d, 1-d, -1+d, 1-d]);
|
||||
vertices = new Float32Array(degenVerts);
|
||||
vertBuf = gl.createBuffer();
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, vertBuf);
|
||||
gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);
|
||||
gl.vertexAttribPointer(0, 2, gl.FLOAT, false, 0, 0);
|
||||
indBuf = gl.createBuffer();
|
||||
var degenInd = new Array(252);
|
||||
for (var j = 0; j < 252; ++j) {
|
||||
degenInd[j] = j;
|
||||
}
|
||||
degenInd = degenInd.concat([252, 253, 254, 255]);
|
||||
indices = new Uint8Array(degenInd);
|
||||
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indBuf);
|
||||
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indices, gl.STATIC_DRAW);
|
||||
|
||||
debug('Draw a square using an ubyte indexed line loop with 256 indices and verify that it draws all four sides and nothing else.');
|
||||
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
|
||||
gl.drawElements(gl.LINE_LOOP, indices.length, gl.UNSIGNED_BYTE, 0);
|
||||
checkLineLoop(gl, w);
|
||||
|
||||
|
||||
//---------- TRIANGLE_FAN ----------
|
||||
vertices = new Float32Array([0, 0, -1, -1, 1, -1, 1, 1, -1, 1, -1, -1]);
|
||||
vertBuf = gl.createBuffer();
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, vertBuf);
|
||||
gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);
|
||||
gl.vertexAttribPointer(0, 2, gl.FLOAT, false, 0, 0);
|
||||
indices = new Uint16Array([0,1,2,3,4,5]);
|
||||
indBuf = gl.createBuffer();
|
||||
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indBuf);
|
||||
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indices, gl.STATIC_DRAW);
|
||||
|
||||
debug('Draw a filled square using a triangle fan and verify that it fills the entire canvas.');
|
||||
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
|
||||
gl.drawArrays(gl.TRIANGLE_FAN, 0, vertices.length / 2);
|
||||
checkTriFan(gl, w);
|
||||
|
||||
debug('Draw a filled square using an indexed triangle fan and verify that it fills the entire canvas.');
|
||||
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
|
||||
gl.drawElements(gl.TRIANGLE_FAN, indices.length, gl.UNSIGNED_SHORT, 0);
|
||||
checkTriFan(gl, w);
|
||||
|
||||
vertices = new Float32Array([1, 1, 1, 1, 1, 1, 0, 0, -1, -1, 1, -1, 1, 1, -1, 1, -1, -1]);
|
||||
vertBuf = gl.createBuffer();
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, vertBuf);
|
||||
gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);
|
||||
gl.vertexAttribPointer(0, 2, gl.FLOAT, false, 0, 0);
|
||||
indices = new Uint16Array([0,1,2,3,4,5,6,7,8]);
|
||||
indBuf = gl.createBuffer();
|
||||
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indBuf);
|
||||
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indices, gl.STATIC_DRAW);
|
||||
|
||||
debug('Draw a filled square using a triangle fan with a vertex buffer offset and verify that it fills the entire canvas.');
|
||||
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
|
||||
gl.drawArrays(gl.TRIANGLE_FAN, 3, vertices.length / 2 - 3);
|
||||
checkTriFan(gl, w);
|
||||
|
||||
debug('Draw a filled square using an indexed triangle fan with an index buffer offset and verify that it fills the entire canvas.');
|
||||
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
|
||||
gl.drawElements(gl.TRIANGLE_FAN, indices.length - 3, gl.UNSIGNED_SHORT, 3 * 2);
|
||||
checkTriFan(gl, w);
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<canvas id="testbed" width="10px" height="10px" style="width:50px; height:50px"></canvas>
|
||||
<div id="description"></div>
|
||||
<div id="console"></div>
|
||||
<script>
|
||||
description('Verify that LINE_LOOP and TRIANGLE_FAN works correctly.');
|
||||
runTest();
|
||||
successfullyParsed = true;
|
||||
</script>
|
||||
<script src="../../resources/js-test-post.js"></script>
|
||||
</body>
|
||||
</html>
|
@ -223,7 +223,10 @@ var runFeatureTest = function(params) {
|
||||
|
||||
var wtu = WebGLTestUtils;
|
||||
var gridRes = params.gridRes;
|
||||
var tolerance = params.tolerance || 0;
|
||||
var vertexTolerance = params.tolerance || 0;
|
||||
var fragmentTolerance = vertexTolerance;
|
||||
if ('fragmentTolerance' in params)
|
||||
fragmentTolerance = params.fragmentTolerance || 0;
|
||||
|
||||
description("Testing GLSL feature: " + params.feature);
|
||||
|
||||
@ -252,13 +255,15 @@ var runFeatureTest = function(params) {
|
||||
input: "color",
|
||||
output: "vColor",
|
||||
vertexShaderTemplate: vertexShaderTemplate,
|
||||
fragmentShaderTemplate: baseFragmentShader
|
||||
fragmentShaderTemplate: baseFragmentShader,
|
||||
tolerance: vertexTolerance
|
||||
},
|
||||
{ type: "fragment",
|
||||
input: "vColor",
|
||||
output: "gl_FragColor",
|
||||
vertexShaderTemplate: baseVertexShader,
|
||||
fragmentShaderTemplate: fragmentShaderTemplate
|
||||
fragmentShaderTemplate: fragmentShaderTemplate,
|
||||
tolerance: fragmentTolerance
|
||||
}
|
||||
];
|
||||
for (var ss = 0; ss < shaderInfos.length; ++ss) {
|
||||
@ -328,7 +333,7 @@ var runFeatureTest = function(params) {
|
||||
}
|
||||
var testImg = makeImage(canvas);
|
||||
|
||||
reportResults(refData, refImg, testData, testImg);
|
||||
reportResults(refData, refImg, testData, testImg, shaderInfo.tolerance);
|
||||
}
|
||||
}
|
||||
|
||||
@ -364,7 +369,7 @@ var runFeatureTest = function(params) {
|
||||
console.appendChild(div);
|
||||
}
|
||||
|
||||
function reportResults(refData, refImage, testData, testImage) {
|
||||
function reportResults(refData, refImage, testData, testImage, tolerance) {
|
||||
var same = true;
|
||||
for (var yy = 0; yy < height; ++yy) {
|
||||
for (var xx = 0; xx < width; ++xx) {
|
||||
@ -487,6 +492,18 @@ return {
|
||||
* tests:
|
||||
* The code for each test. It is assumed the tests are for
|
||||
* float, vec2, vec3, vec4 in that order.
|
||||
*
|
||||
* tolerance: (optional)
|
||||
* Allow some tolerance in the comparisons. The tolerance is applied to
|
||||
* both vertex and fragment shaders. The default tolerance is 0, meaning
|
||||
* the values have to be identical.
|
||||
*
|
||||
* fragmentTolerance: (optional)
|
||||
* Specify a tolerance which only applies to fragment shaders. The
|
||||
* fragment-only tolerance will override the shared tolerance for
|
||||
* fragment shaders if both are specified. Fragment shaders usually
|
||||
* use mediump float precision so they sometimes require higher tolerance
|
||||
* than vertex shaders which use highp.
|
||||
*/
|
||||
runFeatureTest: runFeatureTest,
|
||||
|
||||
|
@ -130,18 +130,33 @@ function shouldGenerateGLError(ctx, glErrors, evalStr) {
|
||||
/**
|
||||
* Tests that the first error GL returns is the specified error.
|
||||
* @param {!WebGLContext} gl The WebGLContext to use.
|
||||
* @param {number} glError The expected gl error.
|
||||
* @param {number|!Array.<number>} glError The expected gl
|
||||
* error. Multiple errors can be passed in using an
|
||||
* array.
|
||||
* @param {string} opt_msg Optional additional message.
|
||||
*/
|
||||
function glErrorShouldBe(gl, glError, opt_msg) {
|
||||
function glErrorShouldBe(gl, glErrors, opt_msg) {
|
||||
if (!glErrors.length) {
|
||||
glErrors = [glErrors];
|
||||
}
|
||||
opt_msg = opt_msg || "";
|
||||
var err = gl.getError();
|
||||
if (err != glError) {
|
||||
testFailed("getError expected: " + getGLErrorAsString(gl, glError) +
|
||||
". Was " + getGLErrorAsString(gl, err) + " : " + opt_msg);
|
||||
var ndx = glErrors.indexOf(err);
|
||||
if (ndx < 0) {
|
||||
if (glErrors.length == 1) {
|
||||
testFailed("getError expected: " + getGLErrorAsString(gl, glErrors[0]) +
|
||||
". Was " + getGLErrorAsString(gl, err) + " : " + opt_msg);
|
||||
} else {
|
||||
var errs = [];
|
||||
for (var ii = 0; ii < glErrors.length; ++ii) {
|
||||
errs.push(getGLErrorAsString(gl, glErrors[ii]));
|
||||
}
|
||||
testFailed("getError expected one of: [" + errs.join(", ") +
|
||||
"]. Was " + getGLErrorAsString(gl, err) + " : " + opt_msg);
|
||||
}
|
||||
} else {
|
||||
testPassed("getError was expected value: " +
|
||||
getGLErrorAsString(gl, glError) + " : " + opt_msg);
|
||||
getGLErrorAsString(gl, err) + " : " + opt_msg);
|
||||
}
|
||||
};
|
||||
|
||||
@ -361,18 +376,18 @@ var getBasePathForResources = function() {
|
||||
|
||||
function loadStandardVertexShader(context) {
|
||||
return loadShader(
|
||||
context,
|
||||
getBasePathForResources() + "vertexShader.vert",
|
||||
context.VERTEX_SHADER,
|
||||
true);
|
||||
context,
|
||||
getBasePathForResources() + "vertexShader.vert",
|
||||
context.VERTEX_SHADER,
|
||||
true);
|
||||
}
|
||||
|
||||
function loadStandardFragmentShader(context) {
|
||||
return loadShader(
|
||||
context,
|
||||
getBasePathForResources() + "fragmentShader.frag",
|
||||
context.FRAGMENT_SHADER,
|
||||
true);
|
||||
context,
|
||||
getBasePathForResources() + "fragmentShader.frag",
|
||||
context.FRAGMENT_SHADER,
|
||||
true);
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -61,8 +61,8 @@ else {
|
||||
debug("");
|
||||
debug("Check default values");
|
||||
shouldBe('context.getParameter(context.ACTIVE_TEXTURE)', 'context.TEXTURE0');
|
||||
shouldBe('(context.getParameter(context.ALIASED_LINE_WIDTH_RANGE)[0] == 1) || (context.getParameter(context.ALIASED_LINE_WIDTH_RANGE)[1] == 1)', 'true');
|
||||
shouldBe('(context.getParameter(context.ALIASED_POINT_SIZE_RANGE)[0] == 1) || (context.getParameter(context.ALIASED_POINT_SIZE_RANGE)[1] == 1)', 'true');
|
||||
shouldBe('(context.getParameter(context.ALIASED_LINE_WIDTH_RANGE)[0] <= 1) && (context.getParameter(context.ALIASED_LINE_WIDTH_RANGE)[0] > 0) && (context.getParameter(context.ALIASED_LINE_WIDTH_RANGE)[1] >= 1)', 'true');
|
||||
shouldBe('(context.getParameter(context.ALIASED_POINT_SIZE_RANGE)[0] <= 1) && (context.getParameter(context.ALIASED_POINT_SIZE_RANGE)[0] > 0) && (context.getParameter(context.ALIASED_POINT_SIZE_RANGE)[1] >= 1)', 'true');
|
||||
shouldBe('context.getParameter(context.ARRAY_BUFFER_BINDING)', 'null');
|
||||
shouldBe('context.getParameter(context.BLEND)', 'false');
|
||||
shouldBe('context.getParameter(context.BLEND_COLOR)', '[0, 0, 0, 0]');
|
||||
|
@ -22,6 +22,7 @@ description("Test texImage2D conversions.");
|
||||
var wtu = WebGLTestUtils;
|
||||
var canvas = document.getElementById("example");
|
||||
var gl = wtu.create3DContext(canvas);
|
||||
gl.disable(gl.DITHER);
|
||||
var program = wtu.setupTexturedQuad(gl);
|
||||
|
||||
glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors from setup.");
|
||||
|
@ -46,6 +46,7 @@ function init()
|
||||
|
||||
var canvas = document.getElementById("example");
|
||||
gl = wtu.create3DContext(canvas);
|
||||
gl.disable(gl.DITHER);
|
||||
var program = wtu.setupTexturedQuad(gl);
|
||||
|
||||
gl.clearColor(0,0,0,1);
|
||||
|
@ -35,6 +35,7 @@ description('Tests texSubImage2D upload path from Uint8Array');
|
||||
var wtu = WebGLTestUtils;
|
||||
var canvas = document.getElementById("example");
|
||||
var gl = wtu.create3DContext(canvas);
|
||||
gl.disable(gl.DITHER);
|
||||
var program = wtu.setupProgram(
|
||||
gl,
|
||||
[wtu.setupSimpleTextureVertexShader(gl),
|
||||
|
@ -211,12 +211,17 @@ function checkRect(x, y, width, height, color) {
|
||||
function fillLevel(target, level, size, color) {
|
||||
var numPixels = size * size;
|
||||
var pixels = new Uint8Array(numPixels * 4);
|
||||
for (var jj = 0; jj < numPixels; ++jj) {
|
||||
var pixelRow = new Uint8Array(size * 4);
|
||||
for (var jj = 0; jj < size; ++jj) {
|
||||
var off = jj * 4;
|
||||
pixels[off + 0] = color[0];
|
||||
pixels[off + 1] = color[1];
|
||||
pixels[off + 2] = color[2];
|
||||
pixels[off + 3] = color[3];
|
||||
pixelRow[off + 0] = color[0];
|
||||
pixelRow[off + 1] = color[1];
|
||||
pixelRow[off + 2] = color[2];
|
||||
pixelRow[off + 3] = color[3];
|
||||
}
|
||||
for (var jj = 0; jj < size; ++jj) {
|
||||
var off = jj * size * 4;
|
||||
pixels.set(pixelRow, off);
|
||||
}
|
||||
gl.texImage2D(
|
||||
target, level, gl.RGBA, size, size, 0, gl.RGBA, gl.UNSIGNED_BYTE,
|
||||
|
@ -14,7 +14,7 @@ found in the LICENSE file.
|
||||
<script src="../resources/webgl-test-utils.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<canvas id="example" width="256" height="256" style="width: 40px; height: 40px;"></canvas>
|
||||
<canvas id="example" width="32" height="32" style="width: 40px; height: 40px;"></canvas>
|
||||
<div id="description"></div>
|
||||
<div id="console"></div>
|
||||
<script id="vshader" type="x-shader/x-vertex">
|
||||
@ -149,14 +149,29 @@ function checkTexture(width, height, cubeMap) {
|
||||
|
||||
function fillLevel(level, width, height, color, opt_cubemap) {
|
||||
var numPixels = width * height;
|
||||
var pixels = new Uint8Array(numPixels * 4);
|
||||
for (var jj = 0; jj < numPixels; ++jj) {
|
||||
var pixels = null;
|
||||
var largeDim = Math.max(width, height);
|
||||
var smallDim = Math.min(width, height);
|
||||
|
||||
var pixelRow = new Uint8Array(largeDim * 4);
|
||||
for (var jj = 0; jj < largeDim; ++jj) {
|
||||
var off = jj * 4;
|
||||
pixels[off + 0] = color[0];
|
||||
pixels[off + 1] = color[1];
|
||||
pixels[off + 2] = color[2];
|
||||
pixels[off + 3] = color[3];
|
||||
pixelRow[off + 0] = color[0];
|
||||
pixelRow[off + 1] = color[1];
|
||||
pixelRow[off + 2] = color[2];
|
||||
pixelRow[off + 3] = color[3];
|
||||
}
|
||||
|
||||
if (largeDim == numPixels) {
|
||||
pixels = pixelRow;
|
||||
} else {
|
||||
var pixels = new Uint8Array(numPixels * 4);
|
||||
for (var jj = 0; jj < smallDim; ++jj) {
|
||||
var off = jj * largeDim * 4;
|
||||
pixels.set(pixelRow, off);
|
||||
}
|
||||
}
|
||||
|
||||
var targets = opt_cubemap ? [
|
||||
gl.TEXTURE_CUBE_MAP_POSITIVE_X,
|
||||
gl.TEXTURE_CUBE_MAP_NEGATIVE_X,
|
||||
|
@ -519,18 +519,14 @@ function testConstructionWithOutOfRangeValues(type, name) {
|
||||
}, "Construction of " + name + " with out-of-range offset");
|
||||
}
|
||||
|
||||
function testConstructionWithNegativeOutOfRangeValues(type, name) {
|
||||
try {
|
||||
var buffer = new ArrayBuffer(-1);
|
||||
testFailed("Construction of ArrayBuffer with negative size should throw exception");
|
||||
} catch (e) {
|
||||
testPassed("Construction of ArrayBuffer with negative size threw exception");
|
||||
}
|
||||
try {
|
||||
var array = new type(-1);
|
||||
testFailed("Construction of " + name + " with negative size should throw exception");
|
||||
} catch (e) {
|
||||
testPassed("Construction of " + name + " with negative size threw exception");
|
||||
function testConstructionWithNegativeOutOfRangeValues(type, name, elementSizeInBytes) {
|
||||
if (elementSizeInBytes > 1) {
|
||||
try {
|
||||
var array = new type(-1);
|
||||
testFailed("Construction of " + name + " with negative size should throw exception");
|
||||
} catch (e) {
|
||||
testPassed("Construction of " + name + " with negative size threw exception");
|
||||
}
|
||||
}
|
||||
shouldThrowIndexSizeErr(function() {
|
||||
var buffer = new ArrayBuffer(4);
|
||||
@ -895,7 +891,7 @@ function runTests() {
|
||||
testCase.expectedValues);
|
||||
testConstructionWithNullBuffer(type, name);
|
||||
testConstructionWithOutOfRangeValues(type, name);
|
||||
testConstructionWithNegativeOutOfRangeValues(type, name);
|
||||
testConstructionWithNegativeOutOfRangeValues(type, name, testCase.elementSizeInBytes);
|
||||
testConstructionWithUnalignedOffset(type, name, testCase.elementSizeInBytes);
|
||||
testConstructionWithUnalignedLength(type, name, testCase.elementSizeInBytes);
|
||||
testConstructionOfHugeArray(type, name, testCase.elementSizeInBytes);
|
||||
|
@ -95,6 +95,15 @@ locationArray0 = contextA.getUniformLocation(programS, "u_array[0]");
|
||||
shouldGenerateGLError(contextA, contextA.NO_ERROR, "contextA.uniform1i(locationSx, 3)");
|
||||
shouldBe("contextA.getUniform(programS, locationSx)", "3");
|
||||
|
||||
// getUniformLocation should return a different object everytime, should not cache and return the same object
|
||||
debug("Testing that getUniformLocation returns a different object everytime");
|
||||
locationSx = contextA.getUniformLocation(programS, "u_struct.x");
|
||||
locationSx2 = contextA.getUniformLocation(programS, "u_struct.x");
|
||||
shouldBeFalse("locationSx === locationSx2");
|
||||
locationSx.foo = {};
|
||||
locationSx2.foo = {};
|
||||
shouldBeFalse("locationSx.foo === locationSx2.foo");
|
||||
|
||||
successfullyParsed = true;
|
||||
</script>
|
||||
|
||||
|
@ -1,22 +0,0 @@
|
||||
# HG changeset patch
|
||||
# Parent 587913950733649a7cbd184a195b08cbb86b2fed
|
||||
diff --git a/content/canvas/test/webgl/conformance/more/00_test_list.txt b/content/canvas/test/webgl/conformance/more/00_test_list.txt
|
||||
--- a/content/canvas/test/webgl/conformance/more/00_test_list.txt
|
||||
+++ b/content/canvas/test/webgl/conformance/more/00_test_list.txt
|
||||
@@ -1,12 +1,15 @@
|
||||
conformance/constants.html
|
||||
conformance/getContext.html
|
||||
conformance/methods.html
|
||||
-conformance/quickCheckAPI.html
|
||||
+#this test causes whichever comes after to intermittently time out.
|
||||
+#forcing a GC run doesn't solve this issue. Could be something about using a random amount of memory that
|
||||
+#can be too high, causing e.g. swapping.
|
||||
+#conformance/quickCheckAPI.html
|
||||
conformance/webGLArrays.html
|
||||
functions/bindBuffer.html
|
||||
functions/bindBufferBadArgs.html
|
||||
functions/bindFramebufferLeaveNonZero.html
|
||||
functions/bufferData.html
|
||||
functions/bufferDataBadArgs.html
|
||||
functions/bufferSubData.html
|
||||
functions/bufferSubDataBadArgs.html
|
@ -1,6 +1,5 @@
|
||||
# HG changeset patch
|
||||
# Parent 95e5d92098ad52788348e609e261305d4b05b551
|
||||
|
||||
# Parent 9c1a90f789e3d43455cb18a9a911627c80c0d9ac
|
||||
diff --git a/content/canvas/test/webgl/conformance/more/functions/readPixelsBadArgs.html b/content/canvas/test/webgl/conformance/more/functions/readPixelsBadArgs.html
|
||||
--- a/content/canvas/test/webgl/conformance/more/functions/readPixelsBadArgs.html
|
||||
+++ b/content/canvas/test/webgl/conformance/more/functions/readPixelsBadArgs.html
|
||||
|
@ -1,3 +1,4 @@
|
||||
conformance/context/context-lost-restored.html
|
||||
conformance/context/premultiplyalpha-test.html
|
||||
conformance/glsl/misc/glsl-long-variable-names.html
|
||||
conformance/glsl/misc/shader-with-256-character-identifier.frag.html
|
||||
|
@ -1,3 +1,4 @@
|
||||
conformance/context/context-lost-restored.html
|
||||
conformance/context/premultiplyalpha-test.html
|
||||
conformance/glsl/misc/glsl-function-nodes.html
|
||||
conformance/glsl/misc/glsl-long-variable-names.html
|
||||
|
@ -1,3 +1,4 @@
|
||||
conformance/context/context-lost-restored.html
|
||||
conformance/context/premultiplyalpha-test.html
|
||||
conformance/glsl/functions/glsl-function-atan.html
|
||||
conformance/glsl/functions/glsl-function-atan-xy.html
|
||||
@ -11,3 +12,5 @@ conformance/glsl/misc/attrib-location-length-limits.html
|
||||
conformance/glsl/misc/struct-nesting-under-maximum.html
|
||||
conformance/glsl/misc/uniform-location-length-limits.html
|
||||
conformance/renderbuffers/framebuffer-object-attachment.html
|
||||
conformance/rendering/line-loop-tri-fan.html
|
||||
|
||||
|
@ -1,16 +1,9 @@
|
||||
# HG changeset patch
|
||||
# Parent 2dbd71999fe8a8da476ab6cc97716f7b7c294fb8
|
||||
# User Doug Sherk <dsherk@mozilla.com>
|
||||
Bug 693703: added additional logging information for mochitests, incl. image reference differences r=bjacob
|
||||
|
||||
Added some code to print to dump output of WebGL mochitest failures. Also added
|
||||
special code to handle incorrect reference images. It will now provide the user
|
||||
with a way to compare the reference and actual drawings.
|
||||
|
||||
# Parent 4ed0bad4933ba69927ee5f75cf67093d3e99566a
|
||||
diff --git a/content/canvas/test/webgl/conformance/glsl/misc/glsl-function-nodes.html b/content/canvas/test/webgl/conformance/glsl/misc/glsl-function-nodes.html
|
||||
--- a/content/canvas/test/webgl/conformance/glsl/misc/glsl-function-nodes.html
|
||||
+++ b/content/canvas/test/webgl/conformance/glsl/misc/glsl-function-nodes.html
|
||||
@@ -115,17 +115,18 @@ function init()
|
||||
@@ -117,17 +117,18 @@ function init()
|
||||
var bufFunction = new Uint8Array(width * height * 4);
|
||||
var bufMacro = new Uint8Array(width * height * 4);
|
||||
|
||||
@ -148,7 +141,7 @@ diff --git a/content/canvas/test/webgl/resources/js-test-pre.js b/content/canvas
|
||||
+
|
||||
+ testFailed(msg);
|
||||
+
|
||||
+ var data = 'REFTEST TEST-UNEXPECTED-FAIL | ' + msg + ' | image comparison (==)\n' +
|
||||
+ var data = 'REFTEST TEST-DEBUG-INFO | ' + msg + ' | image comparison (==)\n' +
|
||||
+ 'REFTEST IMAGE 1 (TEST): ' + testData + '\n' +
|
||||
+ 'REFTEST IMAGE 2 (REFERENCE): ' + refData;
|
||||
+ dump('FAIL: ' + data + '\n');
|
||||
|
@ -1,6 +1,5 @@
|
||||
# HG changeset patch
|
||||
# Parent 041265c6ac29c43856a8df4d4581cb6a04b95a68
|
||||
|
||||
# Parent bf9d7872738cdb7cf425e6dd060ae62882487e1a
|
||||
diff --git a/content/canvas/test/webgl/conformance/extensions/oes-standard-derivatives.html b/content/canvas/test/webgl/conformance/extensions/oes-standard-derivatives.html
|
||||
--- a/content/canvas/test/webgl/conformance/extensions/oes-standard-derivatives.html
|
||||
+++ b/content/canvas/test/webgl/conformance/extensions/oes-standard-derivatives.html
|
||||
|
@ -1,5 +1,6 @@
|
||||
# HG changeset patch
|
||||
# Parent 0e44920c4e5e697f86e0a42b909c5a032d70a1a4
|
||||
# Parent 41137626edf2a358f2be1b7ed3f83211230ab4f5
|
||||
|
||||
diff --git a/content/canvas/test/webgl/resources/webgl-test-harness.js b/content/canvas/test/webgl/resources/webgl-test-harness.js
|
||||
--- a/content/canvas/test/webgl/resources/webgl-test-harness.js
|
||||
+++ b/content/canvas/test/webgl/resources/webgl-test-harness.js
|
||||
|
Loading…
Reference in New Issue
Block a user