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/webgl-test-utils.js"></script>
<script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script>
</head>
<body>
<canvas id="example" width="2" height="2"></canvas>
<div id="description"></div>
<div id="console"></div>
<script>
"use strict";
description('Verifies tex{Sub}Image{2|3}D code paths taking partial ArrayBufferView');
var wtu = WebGLTestUtils;
var tiu = TexImageUtils;
function createSource(width, height, depth, viewType, offset) {
var size = width * height * depth * 4; // RGBA
var buf = new window[viewType](size + offset);
for (var ii = 0; ii < size; ++ii) {
if (viewType == "Float32Array")
buf[ii + offset] = ii / 255.0;
else
buf[ii + offset] = ii;
}
return buf;
}
function comparePixels(ref, refOffset, data, tol) {
for (var ii = 0; ii < data.length; ++ii) {
// Skip alpha due to shader's handling of alpha values.
if (ii % 4 == 3)
continue;
var src = ref[ii + refOffset];
if (ref instanceof Float32Array)
src *= 255;
if (Math.abs(src - data[ii]) > tol) {
testFailed("Element " + ii + ": expected " + src + ", got " + data[ii]);
return;
}
}
return testPassed("texture data uploaded correctly");
}
function run2DTest(gl, test, width, height, srcOffset, tol) {
debug("");
debug("Tesing tex{Sub}Image2D with sub source: internalformat = " + test.internalformat +
", format = " + test.format + ", type = " + test.type);
var program = tiu.setupTexturedQuad(gl, test.internalformat);
if (!program) {
testFailed("Failed to set up program");
return;
}
var buf = createSource(width, height, 1, test.viewType, srcOffset);
var texture = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, texture);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
gl.texImage2D(gl.TEXTURE_2D, 0, gl[test.internalformat], width, height, 0,
gl[test.format], gl[test.type], buf, srcOffset + 1);
wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "srcOffset too large");
gl.texImage2D(gl.TEXTURE_2D, 0, gl[test.internalformat], width, height, 0,
gl[test.format], gl[test.type], buf, srcOffset);
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "texImage2D succeeds with correct buffer and srcOffset");
wtu.clearAndDrawUnitQuad(gl, [0, 0, 0, 255]);
var readBuf = new Uint8Array(width * height * 4);
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, readBuf);
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "no error");
var tol = 0.5;
comparePixels(buf, srcOffset, readBuf, tol);
gl.texImage2D(gl.TEXTURE_2D, 0, gl[test.internalformat], width, height, 0,
gl[test.format], gl[test.type], null);
gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, width, height, gl[test.format], gl[test.type],
buf, srcOffset + 1);
wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "srcOffset too large");
gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, width, height, gl[test.format], gl[test.type],
buf, srcOffset);
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "texSubImage2D succeeds with correct buffer and srcOffset");
wtu.clearAndDrawUnitQuad(gl, [0, 0, 0, 255]);
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, readBuf);
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "no error");
comparePixels(buf, srcOffset, readBuf, tol);
gl.deleteTexture(texture);
gl.deleteProgram(program);
}
function run3DTest(gl, test, width, height, srcOffset, tol) {
debug("");
debug("Tesing tex{Sub}Image3D with sub source: internalformat = " + test.internalformat +
", format = " + test.format + ", type = " + test.type);
var program = tiu.setupTexturedQuadWith3D(gl, test.internalformat);
if (!program) {
testFailed("Failed to set up program");
return;
}
var depth = 1;
var buf = createSource(width, height, depth, test.viewType, srcOffset);
var texture = gl.createTexture();
gl.bindTexture(gl.TEXTURE_3D, texture);
gl.texParameteri(gl.TEXTURE_3D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_3D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_3D, gl.TEXTURE_WRAP_R, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_3D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_3D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
gl.texImage3D(gl.TEXTURE_3D, 0, gl[test.internalformat], width, height, depth, 0,
gl[test.format], gl[test.type], buf, srcOffset + 1);
wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "srcOffset too large");
gl.texImage3D(gl.TEXTURE_3D, 0, gl[test.internalformat], width, height, depth, 0,
gl[test.format], gl[test.type], buf, srcOffset);
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "texImage3D succeeds with correct buffer and srcOffset");
wtu.clearAndDrawUnitQuad(gl, [0, 0, 0, 255]);
var readBuf = new Uint8Array(width * height * 4);
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, readBuf);
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "no error");
var tol = 0.5;
comparePixels(buf, srcOffset, readBuf, tol);
gl.texImage3D(gl.TEXTURE_3D, 0, gl[test.internalformat], width, height, depth, 0,
gl[test.format], gl[test.type], null);
gl.texSubImage3D(gl.TEXTURE_3D, 0, 0, 0, 0, width, height, depth, gl[test.format], gl[test.type],
buf, srcOffset + 1);
wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "srcOffset too large");
gl.texSubImage3D(gl.TEXTURE_3D, 0, 0, 0, 0, width, height, depth, gl[test.format], gl[test.type],
buf, srcOffset);
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "texSubImage3D succeeds with correct buffer and srcOffset");
wtu.clearAndDrawUnitQuad(gl, [0, 0, 0, 255]);
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, readBuf);
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "no error");
comparePixels(buf, srcOffset, readBuf, tol);
gl.deleteTexture(texture);
gl.deleteProgram(program);
}
var gl = wtu.create3DContext("example", undefined, 2);
if (!gl) {
testFailed("Fail to get a WebGL context");
} else {
var testCases = [
{ internalformat: 'RGBA8', format: 'RGBA', type: 'UNSIGNED_BYTE',
viewType: 'Uint8Array', },
{ internalformat: 'RGBA8I', format: 'RGBA_INTEGER', type: 'BYTE',
viewType: 'Int8Array', },
{ internalformat: 'RGBA16UI', format: 'RGBA_INTEGER', type: 'UNSIGNED_SHORT',
viewType: 'Uint16Array', },
{ internalformat: 'RGBA16I', format: 'RGBA_INTEGER', type: 'SHORT',
viewType: 'Int16Array', },
{ internalformat: 'RGBA32UI', format: 'RGBA_INTEGER', type: 'UNSIGNED_INT',
viewType: 'Uint32Array', },
{ internalformat: 'RGBA32I', format: 'RGBA_INTEGER', type: 'INT',
viewType: 'Int32Array', },
{ internalformat: 'RGBA32F', format: 'RGBA', type: 'FLOAT',
viewType: 'Float32Array', },
];
var srcOffset = 3;
var tol = 0.5;
for (var idx = 0; idx < testCases.length; ++idx) {
run2DTest(gl, testCases[idx], gl.drawingBufferWidth, gl.drawingBufferHeight, srcOffset, tol);
run3DTest(gl, testCases[idx], gl.drawingBufferWidth, gl.drawingBufferHeight, srcOffset, tol);
}
}
var successfullyParsed = true;
</script>
<script src="../../../js/js-test-post.js"></script>
</body>
</html>