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">
<title>WebGL EXT_texture_norm16 Conformance Tests</title>
<LINK rel="stylesheet" href="../../resources/js-test-style.css"/>
<script src="../../js/js-test-pre.js"></script>
<script src="../../js/webgl-test-utils.js"></script>
</head>
<body>
<div id="description"></div>
<div id="console"></div>
<script>
"use strict";
description("This test verifies the functionality of the EXT_texture_norm16 extension, if it is available.");
debug("");
var wtu = WebGLTestUtils;
var gl = wtu.create3DContext(null, null, 2);
var ext;
var formats = null;
var textures;
var fbos;
var renderbuffer;
var readbackBuf = new Uint16Array(4);
function generateFormatColor(format, value, alpha) {
alpha = alpha !== undefined ? alpha : 255;
switch(format) {
case gl.RED:
return [value, 0, 0, alpha];
case gl.RG:
return [value, value, 0, alpha];
case gl.RGB:
return [value, value, value, alpha];
case gl.RGBA:
return [value, value, value, value];
default:
wtu.error("Unreachable: Unknown format.");
return null;
}
}
function testNorm16Texture(internalFormat, format, type, error="NO_ERROR") {
debug(`\ntestNorm16Texture(${[].slice.call(arguments).join(", ")})`);
let pixelValue;
let expectedValue;
let imageData;
switch(gl[type]) {
case gl.SHORT:
pixelValue = 0x7fff;
expectedValue = 0xff;
imageData = new Int16Array(4).fill(pixelValue);
break;
case gl.UNSIGNED_SHORT:
pixelValue = 0x6a35;
expectedValue = pixelValue >> 8;
imageData = new Uint16Array(4).fill(pixelValue);
break;
default:
wtu.error("Unreachable: Unknown texture type.");
break;
}
// Texture sampled from
gl.activeTexture(gl.TEXTURE0);
gl.bindTexture(gl.TEXTURE_2D, textures[0]);
gl.texImage2D(gl.TEXTURE_2D, 0, ext[internalFormat] || gl[internalFormat],
1, 1, 0, gl[format], gl[type], imageData);
wtu.glErrorShouldBe(gl, gl[error], `texImage should generate error:${error}`);
if (gl[error]) return;
gl.drawArrays(gl.TRIANGLES, 0, 6);
// Read back as gl.UNSIGNED_BYTE
wtu.checkCanvasRect(gl, 0, 0, 1, 1, generateFormatColor(gl[format], expectedValue));
}
function testNorm16Render(interalFormat, format, type, tolerance) {
// Only UNSIGNED_SHORT are renderable
let pixelValue = 0x6a35;
let expectedValue = pixelValue;
let imageData = new Uint16Array(4).fill(pixelValue);
// Render to fbo texture attachment test
gl.bindTexture(gl.TEXTURE_2D, textures[1]);
gl.texImage2D(gl.TEXTURE_2D, 0, interalFormat, 1, 1, 0, format, type, null);
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "rtt bindings succeed");
gl.bindFramebuffer(gl.FRAMEBUFFER, fbos[0]);
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, textures[1], 0);
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "fbo bindings succeed");
gl.activeTexture(gl.TEXTURE0);
gl.bindTexture(gl.TEXTURE_2D, textures[0]);
gl.texImage2D(gl.TEXTURE_2D, 0, interalFormat, 1, 1, 0, format, type, imageData);
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "texture bindings succeed");
gl.drawArrays(gl.TRIANGLES, 0, 6);
wtu.checkCanvasRect(gl, 0, 0, 1, 1, generateFormatColor(format, expectedValue, 0xffff), undefined, tolerance, readbackBuf, type);
// Renderbuffer test
gl.bindFramebuffer(gl.FRAMEBUFFER, fbos[1]);
gl.bindRenderbuffer(gl.RENDERBUFFER, renderbuffer);
gl.renderbufferStorage(gl.RENDERBUFFER, interalFormat, 1, 1);
gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER,
renderbuffer);
gl.bindRenderbuffer(gl.RENDERBUFFER, null);
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "renderbuffer bindings succeed");
gl.clearColor(1, 1, 1, 1);
gl.clear(gl.COLOR_BUFFER_BIT);
wtu.checkCanvasRect(gl, 0, 0, 1, 1, generateFormatColor(format, 0xffff, 0xffff), undefined, tolerance, readbackBuf, type);
// Copy from renderbuffer to textures[1] test
gl.bindTexture(gl.TEXTURE_2D, textures[1]);
gl.copyTexSubImage2D(gl.TEXTURE_2D, 0, 0, 0, 0, 0, 1, 1);
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "copy succeed");
gl.bindFramebuffer(gl.FRAMEBUFFER, fbos[0]);
wtu.checkCanvasRect(gl, 0, 0, 1, 1, generateFormatColor(format, 0xffff, 0xffff), undefined, tolerance, readbackBuf, type);
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
gl.bindTexture(gl.TEXTURE_2D, null);
}
function testExtFormatUnrenderable(internalFormatName, format, type) {
gl.bindTexture(gl.TEXTURE_2D, textures[1]);
gl.texImage2D(gl.TEXTURE_2D, 0, ext[internalFormatName], 1, 1, 0, format, type, null);
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "texture definition succeeded");
gl.bindFramebuffer(gl.FRAMEBUFFER, fbos[0]);
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, textures[1], 0);
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "fbo binding succeeded");
wtu.framebufferStatusShouldBe(gl, gl.FRAMEBUFFER, [ gl.FRAMEBUFFER_INCOMPLETE_ATTACHMENT, gl.FRAMEBUFFER_UNSUPPORTED ],
`framebuffer should not be complete with ${internalFormatName} texture attached`);
}
function runInternalFormatQueryTest()
{
debug("");
debug("testing the internal format query");
var maxSamples = gl.getParameter(gl.MAX_SAMPLES);
const formats = [ext.R16_EXT, ext.RG16_EXT, ext.RGBA16_EXT];
for (const format of formats) {
var samples = gl.getInternalformatParameter(gl.RENDERBUFFER, format, gl.SAMPLES);
if (samples == null || samples.length == 0 || samples[0] < maxSamples) {
testFailed("the maximum value in SAMPLES should be at least " + maxSamples);
return;
}
}
testPassed("Internal format query succeeded");
}
function runTestExtension() {
textures = [gl.createTexture(), gl.createTexture()];
fbos = [gl.createFramebuffer(), gl.createFramebuffer()];
renderbuffer = gl.createRenderbuffer();
for (let i = 0; i < 2; i++) {
gl.bindTexture(gl.TEXTURE_2D, textures[i]);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
}
gl.bindTexture(gl.TEXTURE_2D, null);
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "texture and framebuffer setup succeed");
let program300 = wtu.setupSimpleTextureProgramESSL300(gl);
let program100 = wtu.setupTexturedQuad(gl, 0, 1, wtu.simpleHighPrecisionTextureFragmentShader);
debug("");
debug("Texture creation");
testNorm16Texture("R16_EXT", "RED", "UNSIGNED_SHORT");
testNorm16Texture("RG16_EXT", "RG", "UNSIGNED_SHORT");
testNorm16Texture("RGB16_EXT", "RGB", "UNSIGNED_SHORT");
testNorm16Texture("RGBA16_EXT", "RGBA", "UNSIGNED_SHORT");
testNorm16Texture("R16_SNORM_EXT", "RED", "SHORT");
testNorm16Texture("RG16_SNORM_EXT", "RG", "SHORT");
testNorm16Texture("RGB16_SNORM_EXT", "RGB", "SHORT");
testNorm16Texture("RGBA16_SNORM_EXT", "RGBA", "SHORT");
testNorm16Texture("RGBA", "RGBA", "UNSIGNED_SHORT", "INVALID_OPERATION");
testNorm16Texture("RGBA", "RGBA", "SHORT", "INVALID_OPERATION");
debug("");
debug("Texture renderability");
testNorm16Render(ext.R16_EXT, gl.RED, gl.UNSIGNED_SHORT, 8);
testNorm16Render(ext.RG16_EXT, gl.RG, gl.UNSIGNED_SHORT, 8);
testNorm16Render(ext.RGBA16_EXT, gl.RGBA, gl.UNSIGNED_SHORT, 8);
gl.useProgram(program300);
testNorm16Render(ext.R16_EXT, gl.RED, gl.UNSIGNED_SHORT, 0);
testNorm16Render(ext.RG16_EXT, gl.RG, gl.UNSIGNED_SHORT, 0);
testExtFormatUnrenderable("RGB16_EXT", gl.RGB, gl.UNSIGNED_SHORT);
testNorm16Render(ext.RGBA16_EXT, gl.RGBA, gl.UNSIGNED_SHORT, 0);
testExtFormatUnrenderable("R16_SNORM_EXT", gl.RED, gl.SHORT);
testExtFormatUnrenderable("RG16_SNORM_EXT", gl.RG, gl.SHORT);
testExtFormatUnrenderable("RGB16_SNORM_EXT", gl.RGB, gl.SHORT);
testExtFormatUnrenderable("RGBA16_SNORM_EXT", gl.RGBA, gl.SHORT);
};
function runTest() {
if (!gl) {
testFailed("context does not exist");
} else {
testPassed("context exists");
ext = gl.getExtension("EXT_texture_norm16");
wtu.runExtensionSupportedTest(gl, "EXT_texture_norm16", ext !== null);
if (ext !== null) {
runInternalFormatQueryTest();
runTestExtension();
} else {
testPassed("No EXT_texture_norm16 support -- this is legal");
}
}
}
runTest();
var successfullyParsed = true;
</script>
<script src="../../js/js-test-post.js"></script>
</body>
</html>