Source code

Revision control

Copy as Markdown

Other Tools

<!--
Copyright (c) 2019 The Khronos Group Inc.
Use of this source code is governed by an MIT-style license that can be
found in the LICENSE.txt file.
-->
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="../../resources/js-test-style.css"/>
<script src="../../js/js-test-pre.js"></script>
<script src="../../js/desktop-gl-constants.js"></script>
<script src="../../js/webgl-test-utils.js"></script>
</head>
<body>
<div id="description"></div>
<div id="console"></div>
<script>
"use strict";
description("Tests texture uploads with ArrayBufferView+offsets");
var wtu = WebGLTestUtils;
var gl = wtu.create3DContext(null, undefined, 2);
console.log(gl.getParameter(gl.VERSION));
////
function arrToStr(arr) {
return "[" + arr.map(x => x.toString()).join(", ") + "]";
}
function shouldBeWas(shouldBe, was, info) {
var text = "Should be " + shouldBe + ", was " + was + ".";
if (info) {
text = info + ": " + text;
}
if (shouldBe == was) {
testPassed(text);
return true;
} else {
testFailed(text);
return false;
}
}
function shouldBeWasArr(shouldBe, was, info) {
if (shouldBe.length != was.length) {
testFailed("Length should be " + shouldBe.length + ", was " + was.length + ".");
return false;
}
return shouldBeWas(arrToStr(shouldBe), arrToStr(was), info);
}
////
// Textures
var fibArr = [
0, 1, 1, 2,
3, 5, 8, 13,
21, 34, 55, 89,
144, 233,
];
var fb = gl.createFramebuffer();
function probeWithBadOffset(fnTest, info) {
fnTest(+(-1|0));
if (!gl.getError()) {
testFailed("Does not support " + info + " with offsets into views.");
return false;
}
return true;
}
// fn(view, offset, expectedError, expectedResult)
do {
var readPixelView = new Uint8Array(4);
var testView = new Uint8Array(fibArr);
function testTexOrSubImage(funcName, fnTexOrSubImage) {
debug("");
debug(funcName);
var fnProbe = function(viewOffset) {
fnTexOrSubImage(gl.RGBA, gl.UNSIGNED_BYTE, testView, viewOffset);
};
if (!probeWithBadOffset(fnProbe, funcName))
return;
for (var i = 0; i <= testView.length+1; i++) {
debug("offset=" + i);
fnTexOrSubImage(gl.RGBA, gl.UNSIGNED_BYTE, testView, i);
var effectiveViewLen = testView.length - i;
if (effectiveViewLen >= 4) {
wtu.glErrorShouldBe(gl, gl.NO_ERROR);
gl.readPixels(0, 0, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, readPixelView);
wtu.glErrorShouldBe(gl, gl.NO_ERROR);
shouldBeWasArr(testView.slice(i, i+4), readPixelView);
} else {
wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION);
}
}
debug("");
var yellow565 = (0x1f << 11) | (0x3f << 5);
var cyan565 = (0x3f << 5) | 0x1f;
var arr565 = [yellow565, cyan565];
var view565 = new Uint16Array(arr565);
function rgb888to565(arr888) {
return ((arr888[0] >> 3) << 11) | ((arr888[1] >> 2) << 5) | (arr888[2] >> 3);
}
for (var i = 0; i <= arr565.length+1; i++) {
debug("rgb565, offset=" + i);
fnTexOrSubImage(gl.RGB, gl.UNSIGNED_SHORT_5_6_5, view565, i);
var effectiveViewLen = arr565.length - i;
if (effectiveViewLen >= 1) {
wtu.glErrorShouldBe(gl, gl.NO_ERROR);
gl.readPixels(0, 0, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, readPixelView);
debug(arrToStr(readPixelView));
wtu.glErrorShouldBe(gl, gl.NO_ERROR);
shouldBeWas(arr565[i], rgb888to565(readPixelView));
} else {
wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION);
}
}
}
var fn2D = function(format, type, view, viewOffset) {
gl.texImage2D(gl.TEXTURE_2D, 0, format, 1, 1, 0, format, type, view, viewOffset);
}
var fnSub2D = function(format, type, view, viewOffset) {
gl.texImage2D(gl.TEXTURE_2D, 0, format, 1, 1, 0, format, type, null);
gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, 1, 1, format, type, view, viewOffset);
}
var fn3D = function(format, type, view, viewOffset) {
gl.texImage3D(gl.TEXTURE_3D, 0, format, 1, 1, 1, 0, format, type, view, viewOffset);
}
var fnSub3D = function(format, type, view, viewOffset) {
gl.texImage3D(gl.TEXTURE_3D, 0, format, 1, 1, 1, 0, format, type, null);
gl.texSubImage3D(gl.TEXTURE_3D, 0, 0, 0, 0, 1, 1, 1, format, type, view, viewOffset);
}
////
var tex2d = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, tex2d);
gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex2d, 0);
testTexOrSubImage("texImage2D", fn2D);
testTexOrSubImage("texSubImage2D", fnSub2D);
////
var tex3d = gl.createTexture();
gl.bindTexture(gl.TEXTURE_3D, tex3d);
gl.texImage3D(gl.TEXTURE_3D, 0, gl.RGBA, 1, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
gl.framebufferTextureLayer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, tex3d, 0, 0);
testTexOrSubImage("texImage3D", fn3D);
testTexOrSubImage("texSubImage3D", fnSub3D);
} while (false);
do {
var compressedFormat = 0;
var compressedByteCount;
if (gl.getExtension("WEBGL_compressed_texture_s3tc")) {
var e = gl.getExtension("WEBGL_compressed_texture_s3tc");
compressedFormat = e.COMPRESSED_RGB_S3TC_DXT1_EXT;
compressedByteCount = 8;
} else if (gl.getExtension("WEBGL_compressed_texture_etc")) {
var e = gl.getExtension("WEBGL_compressed_texture_etc");
compressedFormat = e.COMPRESSED_RGB8_ETC2;
compressedByteCount = 8;
} else {
debug("No compressed texture format found. Skipping compressedTex(Sub)Image tests.");
break;
}
////
var view = new Uint8Array(compressedByteCount+1);
var fn2D = function(viewOffset) {
gl.compressedTexImage2D(gl.TEXTURE_2D, 0, compressedFormat, 4, 4, 0,
view, viewOffset, compressedByteCount);
};
var fnSub2D = function(viewOffset) {
gl.compressedTexImage2D(gl.TEXTURE_2D, 0, compressedFormat, 4, 4, 0,
view, 0, compressedByteCount);
gl.compressedTexSubImage2D(gl.TEXTURE_2D, 0, 0, 0, 4, 4, compressedFormat,
view, viewOffset, compressedByteCount);
};
var fn3D = function(viewOffset) {
gl.compressedTexImage3D(gl.TEXTURE_2D_ARRAY, 0, compressedFormat, 4, 4, 1, 0,
view, viewOffset, compressedByteCount);
};
var fnSub3D = function(viewOffset) {
gl.compressedTexImage3D(gl.TEXTURE_2D_ARRAY, 0, compressedFormat, 4, 4, 1, 0,
view, 0, compressedByteCount);
gl.compressedTexSubImage3D(gl.TEXTURE_2D_ARRAY, 0, 0, 0, 0, 4, 4, 1, compressedFormat,
view, viewOffset, compressedByteCount);
};
////
var testFunc = function(funcName, fnToTest) {
debug("");
debug(funcName);
if (!probeWithBadOffset(fnToTest, funcName))
return;
var viewLength = view.length;
var subViewLength = compressedByteCount;
for (var i = 0; i <= viewLength+1; i++) {
debug("offset=" + i);
fnToTest(i);
var effectiveViewLen = viewLength - i;
if (effectiveViewLen >= subViewLength) {
wtu.glErrorShouldBe(gl, gl.NO_ERROR);
} else {
wtu.glErrorShouldBe(gl, gl.INVALID_VALUE);
}
}
};
var tex2d = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, tex2d);
testFunc("compressedTexImage2D" , fn2D );
testFunc("compressedTexSubImage2D", fnSub2D);
var tex3d = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D_ARRAY, tex3d);
testFunc("compressedTexImage3D" , fn3D );
testFunc("compressedTexSubImage3D", fnSub3D);
} while (false);
do {
debug("");
debug("readPixels");
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
var testColor = [10, 20, 30, 40];
gl.clearColor(testColor[0]/255.0,
testColor[1]/255.0,
testColor[2]/255.0,
testColor[3]/255.0);
gl.clear(gl.COLOR_BUFFER_BIT);
var readPixelView = new Uint8Array(6);
function doReadPixels(viewOffset) {
gl.readPixels(0, 0, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, readPixelView, viewOffset);
return readPixelView;
}
if (!probeWithBadOffset(doReadPixels, "doReadPixels"))
break;
for (var i = 0; i <= readPixelView.length+1; i++) {
debug("offset=" + i);
var res = doReadPixels(i);
var effectiveViewLen = readPixelView.length - i;
if (effectiveViewLen >= 4) {
wtu.glErrorShouldBe(gl, gl.NO_ERROR);
shouldBeWasArr(testColor, res.slice(i,i+4));
} else if (effectiveViewLen >= 0) {
wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION);
} else {
wtu.glErrorShouldBe(gl, gl.INVALID_VALUE);
}
}
} while (false);
debug("")
var successfullyParsed = true;
</script>
<script src="../../js/js-test-post.js"></script>
</body>
</html>