mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-20 07:17:32 +09:00
753 lines
25 KiB
HTML
753 lines
25 KiB
HTML
|
|
<!DOCTYPE html>
|
||
|
|
<html>
|
||
|
|
<head>
|
||
|
|
<meta charset="utf-8">
|
||
|
|
<script src="/tests/SimpleTest/SimpleTest.js"></script>
|
||
|
|
<link rel="stylesheet" href="/tests/SimpleTest/test.css">
|
||
|
|
<script src="webgl-util.js"></script>
|
||
|
|
<script src="es3-data.js"></script>
|
||
|
|
<title>WebGL test: test WEBGL_compressed_texture_es3 extension</title>
|
||
|
|
<style>
|
||
|
|
img {
|
||
|
|
border: 1px solid black;
|
||
|
|
margin-right: 1em;
|
||
|
|
}
|
||
|
|
.testimages {
|
||
|
|
}
|
||
|
|
|
||
|
|
.testimages br {
|
||
|
|
clear: both;
|
||
|
|
}
|
||
|
|
|
||
|
|
.testimages > div {
|
||
|
|
float: left;
|
||
|
|
margin: 1em;
|
||
|
|
}
|
||
|
|
</style>
|
||
|
|
</head>
|
||
|
|
<body>
|
||
|
|
<div id="description"></div>
|
||
|
|
<canvas id="canvas" width="8" height="8"></canvas>
|
||
|
|
<div id="console"></div>
|
||
|
|
<script id="vshader" type="x-shader/x-vertex">
|
||
|
|
attribute vec4 vPosition;
|
||
|
|
attribute vec2 texCoord0;
|
||
|
|
varying vec2 texCoord;
|
||
|
|
void main() {
|
||
|
|
gl_Position = vPosition;
|
||
|
|
texCoord = texCoord0;
|
||
|
|
}
|
||
|
|
</script>
|
||
|
|
<script id="fshader" type="x-shader/x-fragment">
|
||
|
|
precision mediump float;
|
||
|
|
uniform sampler2D tex;
|
||
|
|
varying vec2 texCoord;
|
||
|
|
void main() {
|
||
|
|
gl_FragData[0] = texture2D(tex, texCoord);
|
||
|
|
}
|
||
|
|
</script>
|
||
|
|
<script id="fshader-r" type="x-shader/x-fragment">
|
||
|
|
precision mediump float;
|
||
|
|
uniform sampler2D tex;
|
||
|
|
varying vec2 texCoord;
|
||
|
|
void main() {
|
||
|
|
vec4 pixel = (texture2D(tex, texCoord));
|
||
|
|
pixel.r = (pixel.r + 1.0) / 2.0;
|
||
|
|
gl_FragData[0] = pixel;
|
||
|
|
}
|
||
|
|
</script>
|
||
|
|
<script id="fshader-rg" type="x-shader/x-fragment">
|
||
|
|
precision mediump float;
|
||
|
|
uniform sampler2D tex;
|
||
|
|
varying vec2 texCoord;
|
||
|
|
void main() {
|
||
|
|
vec4 pixel = (texture2D(tex, texCoord));
|
||
|
|
pixel.rg = (pixel.rg + 1.0) / 2.0;
|
||
|
|
gl_FragData[0] = pixel;
|
||
|
|
}
|
||
|
|
</script>
|
||
|
|
<script>
|
||
|
|
"use strict";
|
||
|
|
var ext = null;
|
||
|
|
var vao = null;
|
||
|
|
var gl = null;
|
||
|
|
var validFormats = {
|
||
|
|
COMPRESSED_R11_EAC : 0x9270,
|
||
|
|
COMPRESSED_SIGNED_R11_EAC : 0x9271,
|
||
|
|
COMPRESSED_RG11_EAC : 0x9272,
|
||
|
|
COMPRESSED_SIGNED_RG11_EAC : 0x9273,
|
||
|
|
COMPRESSED_RGB8_ETC2 : 0x9274,
|
||
|
|
COMPRESSED_SRGB8_ETC2 : 0x9275,
|
||
|
|
COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 : 0x9276,
|
||
|
|
COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2 : 0x9277,
|
||
|
|
COMPRESSED_RGBA8_ETC2_EAC : 0x9278,
|
||
|
|
COMPRESSED_SRGB8_ALPHA8_ETC2_EAC : 0x9279,
|
||
|
|
};
|
||
|
|
var name;
|
||
|
|
var supportedFormats;
|
||
|
|
|
||
|
|
function setupUnitQuad() {
|
||
|
|
var vertexObject = gl.createBuffer();
|
||
|
|
gl.bindBuffer(gl.ARRAY_BUFFER, vertexObject);
|
||
|
|
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
|
||
|
|
1.0, 1.0, 0.0,
|
||
|
|
-1.0, 1.0, 0.0,
|
||
|
|
-1.0, -1.0, 0.0,
|
||
|
|
1.0, 1.0, 0.0,
|
||
|
|
-1.0, -1.0, 0.0,
|
||
|
|
1.0, -1.0, 0.0]), gl.STATIC_DRAW);
|
||
|
|
gl.enableVertexAttribArray(0);
|
||
|
|
gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 0, 0);
|
||
|
|
|
||
|
|
var vertexObject = gl.createBuffer();
|
||
|
|
gl.bindBuffer(gl.ARRAY_BUFFER, vertexObject);
|
||
|
|
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
|
||
|
|
1.0, 1.0,
|
||
|
|
0.0, 1.0,
|
||
|
|
0.0, 0.0,
|
||
|
|
1.0, 1.0,
|
||
|
|
0.0, 0.0,
|
||
|
|
1.0, 0.0]), gl.STATIC_DRAW);
|
||
|
|
gl.enableVertexAttribArray(1);
|
||
|
|
gl.vertexAttribPointer(1, 2, gl.FLOAT, false, 0, 0);
|
||
|
|
}
|
||
|
|
|
||
|
|
function runTest() {
|
||
|
|
gl = WebGLUtil.getWebGL("canvas", false, {antialias: false});
|
||
|
|
if (!gl) {
|
||
|
|
ok(false, "WebGL context does not exist");
|
||
|
|
} else {
|
||
|
|
ok(true, "WebGL context exists");
|
||
|
|
setupUnitQuad();
|
||
|
|
|
||
|
|
// Run tests with extension disabled
|
||
|
|
runTestDisabled();
|
||
|
|
|
||
|
|
// Query the extension and store globally so shouldBe can access it
|
||
|
|
ext = gl.getExtension("WEBGL_compressed_texture_es3");
|
||
|
|
if (!ext) {
|
||
|
|
ok(true, "No WEBGL_compressed_texture_es3 support -- this is legal");
|
||
|
|
runSupportedTest(false);
|
||
|
|
} else {
|
||
|
|
ok(true, "Successfully enabled WEBGL_compressed_texture_es3 extension");
|
||
|
|
|
||
|
|
runSupportedTest(true);
|
||
|
|
runTestExtension();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
SimpleTest.finish();
|
||
|
|
}
|
||
|
|
|
||
|
|
function runSupportedTest(extensionEnabled) {
|
||
|
|
var supported = gl.getSupportedExtensions();
|
||
|
|
if (supported.indexOf("WEBGL_compressed_texture_es3") >= 0) {
|
||
|
|
if (extensionEnabled) {
|
||
|
|
ok(true, "WEBGL_compressed_texture_es3 listed as supported and getExtension succeeded");
|
||
|
|
} else {
|
||
|
|
ok(false, "WEBGL_compressed_texture_es3 listed as supported but getExtension failed");
|
||
|
|
}
|
||
|
|
} else {
|
||
|
|
if (extensionEnabled) {
|
||
|
|
ok(false, "WEBGL_compressed_texture_es3 not listed as supported but getExtension succeeded");
|
||
|
|
} else {
|
||
|
|
ok(true, "WEBGL_compressed_texture_es3 not listed as supported and getExtension failed -- this is legal");
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
function runTestDisabled() {
|
||
|
|
is(gl.getParameter(gl.COMPRESSED_TEXTURE_FORMATS).length, 0,
|
||
|
|
"Should be no compressed texture formats");
|
||
|
|
}
|
||
|
|
|
||
|
|
function formatExists(format, supportedFormats) {
|
||
|
|
for (var ii = 0; ii < supportedFormats.length; ++ii) {
|
||
|
|
if (format == supportedFormats[ii]) {
|
||
|
|
ok(true, "supported format " + formatToString(format) + " is exists");
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
ok(false, "supported format " + formatToString(format) + " does not exist");
|
||
|
|
}
|
||
|
|
|
||
|
|
function formatToString(format) {
|
||
|
|
for (var p in ext) {
|
||
|
|
if (ext[p] == format) {
|
||
|
|
return p;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return "0x" + format.toString(16);
|
||
|
|
}
|
||
|
|
|
||
|
|
function runTestExtension() {
|
||
|
|
// check that all format enums exist.
|
||
|
|
for (name in validFormats) {
|
||
|
|
is(ext[name], validFormats[name], "format is match");
|
||
|
|
}
|
||
|
|
|
||
|
|
supportedFormats = gl.getParameter(gl.COMPRESSED_TEXTURE_FORMATS);
|
||
|
|
// There should be exactly 10 formats
|
||
|
|
is(supportedFormats.length, 10, "Should be exactly 10 formats");
|
||
|
|
|
||
|
|
// check that all 10 formats exist
|
||
|
|
for (var name in validFormats.length) {
|
||
|
|
formatExists(validFormats[name], supportedFormats);
|
||
|
|
}
|
||
|
|
|
||
|
|
// Test each format
|
||
|
|
testETC2_RGB();
|
||
|
|
}
|
||
|
|
|
||
|
|
function testETC2_RGB() {
|
||
|
|
var tests = [
|
||
|
|
{
|
||
|
|
width: 4,
|
||
|
|
height: 4,
|
||
|
|
channels: 1,
|
||
|
|
data: img_4x4_r11_eac,
|
||
|
|
format: ext.COMPRESSED_R11_EAC
|
||
|
|
},
|
||
|
|
{
|
||
|
|
width: 4,
|
||
|
|
height: 4,
|
||
|
|
channels: 1,
|
||
|
|
data: img_4x4_signed_r11_eac,
|
||
|
|
format: ext.COMPRESSED_SIGNED_R11_EAC
|
||
|
|
},
|
||
|
|
{
|
||
|
|
width: 4,
|
||
|
|
height: 4,
|
||
|
|
channels: 2,
|
||
|
|
data: img_4x4_rg11_eac,
|
||
|
|
format: ext.COMPRESSED_RG11_EAC
|
||
|
|
},
|
||
|
|
{
|
||
|
|
width: 4,
|
||
|
|
height: 4,
|
||
|
|
channels: 2,
|
||
|
|
data: img_4x4_signed_rg11_eac,
|
||
|
|
format: ext.COMPRESSED_SIGNED_RG11_EAC
|
||
|
|
},
|
||
|
|
{
|
||
|
|
width: 4,
|
||
|
|
height: 4,
|
||
|
|
channels: 3,
|
||
|
|
data: img_4x4_rgb_etc2,
|
||
|
|
format: ext.COMPRESSED_RGB8_ETC2
|
||
|
|
},
|
||
|
|
{
|
||
|
|
width: 4,
|
||
|
|
height: 4,
|
||
|
|
channels: 3,
|
||
|
|
data: img_4x4_rgb_etc2,
|
||
|
|
format: ext.COMPRESSED_SRGB8_ETC2
|
||
|
|
},
|
||
|
|
{
|
||
|
|
width: 4,
|
||
|
|
height: 4,
|
||
|
|
channels: 4,
|
||
|
|
data: img_4x4_rgb_punchthrough_etc2,
|
||
|
|
format: ext.COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2
|
||
|
|
},
|
||
|
|
{
|
||
|
|
width: 4,
|
||
|
|
height: 4,
|
||
|
|
channels: 4,
|
||
|
|
data: img_4x4_rgb_punchthrough_etc2,
|
||
|
|
format: ext.COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2
|
||
|
|
},
|
||
|
|
{
|
||
|
|
width: 4,
|
||
|
|
height: 4,
|
||
|
|
channels: 4,
|
||
|
|
data: img_4x4_rgba_etc2,
|
||
|
|
format: ext.COMPRESSED_RGBA8_ETC2_EAC
|
||
|
|
},
|
||
|
|
{
|
||
|
|
width: 4,
|
||
|
|
height: 4,
|
||
|
|
channels: 4,
|
||
|
|
data: img_4x4_rgba_etc2,
|
||
|
|
format: ext.COMPRESSED_SRGB8_ALPHA8_ETC2_EAC
|
||
|
|
},
|
||
|
|
{
|
||
|
|
width: 8,
|
||
|
|
height: 8,
|
||
|
|
channels: 1,
|
||
|
|
data: img_8x8_r11_eac,
|
||
|
|
format: ext.COMPRESSED_R11_EAC
|
||
|
|
},
|
||
|
|
{
|
||
|
|
width: 8,
|
||
|
|
height: 8,
|
||
|
|
channels: 1,
|
||
|
|
data: img_8x8_signed_r11_eac,
|
||
|
|
format: ext.COMPRESSED_SIGNED_R11_EAC
|
||
|
|
},
|
||
|
|
{
|
||
|
|
width: 8,
|
||
|
|
height: 8,
|
||
|
|
channels: 2,
|
||
|
|
data: img_8x8_rg11_eac,
|
||
|
|
format: ext.COMPRESSED_RG11_EAC
|
||
|
|
},
|
||
|
|
{
|
||
|
|
width: 8,
|
||
|
|
height: 8,
|
||
|
|
channels: 2,
|
||
|
|
data: img_8x8_signed_rg11_eac,
|
||
|
|
format: ext.COMPRESSED_SIGNED_RG11_EAC
|
||
|
|
},
|
||
|
|
{
|
||
|
|
width: 8,
|
||
|
|
height: 8,
|
||
|
|
channels: 3,
|
||
|
|
data: img_8x8_rgb_etc2,
|
||
|
|
format: ext.COMPRESSED_RGB8_ETC2
|
||
|
|
},
|
||
|
|
{
|
||
|
|
width: 8,
|
||
|
|
height: 8,
|
||
|
|
channels: 3,
|
||
|
|
data: img_8x8_rgb_etc2,
|
||
|
|
format: ext.COMPRESSED_SRGB8_ETC2
|
||
|
|
},
|
||
|
|
{
|
||
|
|
width: 8,
|
||
|
|
height: 8,
|
||
|
|
channels: 4,
|
||
|
|
data: img_8x8_rgb_punchthrough_etc2,
|
||
|
|
format: ext.COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2
|
||
|
|
},
|
||
|
|
{
|
||
|
|
width: 8,
|
||
|
|
height: 8,
|
||
|
|
channels: 4,
|
||
|
|
data: img_8x8_rgb_punchthrough_etc2,
|
||
|
|
format: ext.COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2
|
||
|
|
},
|
||
|
|
{
|
||
|
|
width: 8,
|
||
|
|
height: 8,
|
||
|
|
channels: 4,
|
||
|
|
data: img_8x8_rgba_etc2,
|
||
|
|
format: ext.COMPRESSED_RGBA8_ETC2_EAC
|
||
|
|
},
|
||
|
|
{
|
||
|
|
width: 8,
|
||
|
|
height: 8,
|
||
|
|
channels: 4,
|
||
|
|
data: img_8x8_rgba_etc2,
|
||
|
|
format: ext.COMPRESSED_SRGB8_ALPHA8_ETC2_EAC
|
||
|
|
},
|
||
|
|
{
|
||
|
|
width: 32,
|
||
|
|
height: 32,
|
||
|
|
channels: 1,
|
||
|
|
data: img_32x32_r11_eac,
|
||
|
|
format: ext.COMPRESSED_R11_EAC
|
||
|
|
},
|
||
|
|
{
|
||
|
|
width: 32,
|
||
|
|
height: 32,
|
||
|
|
channels: 1,
|
||
|
|
data: img_32x32_signed_r11_eac,
|
||
|
|
format: ext.COMPRESSED_SIGNED_R11_EAC
|
||
|
|
},
|
||
|
|
{
|
||
|
|
width: 32,
|
||
|
|
height: 32,
|
||
|
|
channels: 2,
|
||
|
|
data: img_32x32_rg11_eac,
|
||
|
|
format: ext.COMPRESSED_RG11_EAC
|
||
|
|
},
|
||
|
|
{
|
||
|
|
width: 32,
|
||
|
|
height: 32,
|
||
|
|
channels: 2,
|
||
|
|
data: img_32x32_signed_rg11_eac,
|
||
|
|
format: ext.COMPRESSED_SIGNED_RG11_EAC
|
||
|
|
},
|
||
|
|
{
|
||
|
|
width: 32,
|
||
|
|
height: 32,
|
||
|
|
channels: 3,
|
||
|
|
data: img_32x32_rgb_etc2,
|
||
|
|
format: ext.COMPRESSED_RGB8_ETC2
|
||
|
|
},
|
||
|
|
{
|
||
|
|
width: 32,
|
||
|
|
height: 32,
|
||
|
|
channels: 3,
|
||
|
|
data: img_32x32_rgb_etc2,
|
||
|
|
format: ext.COMPRESSED_SRGB8_ETC2
|
||
|
|
},
|
||
|
|
{
|
||
|
|
width: 32,
|
||
|
|
height: 32,
|
||
|
|
channels: 4,
|
||
|
|
data: img_32x32_rgb_punchthrough_etc2,
|
||
|
|
format: ext.COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2
|
||
|
|
},
|
||
|
|
{
|
||
|
|
width: 32,
|
||
|
|
height: 32,
|
||
|
|
channels: 4,
|
||
|
|
data: img_32x32_rgb_punchthrough_etc2,
|
||
|
|
format: ext.COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2
|
||
|
|
},
|
||
|
|
{
|
||
|
|
width: 32,
|
||
|
|
height: 32,
|
||
|
|
channels: 4,
|
||
|
|
data: img_32x32_rgba_etc2,
|
||
|
|
format: ext.COMPRESSED_RGBA8_ETC2_EAC
|
||
|
|
},
|
||
|
|
{
|
||
|
|
width: 32,
|
||
|
|
height: 32,
|
||
|
|
channels: 4,
|
||
|
|
data: img_32x32_rgba_etc2,
|
||
|
|
format: ext.COMPRESSED_SRGB8_ALPHA8_ETC2_EAC
|
||
|
|
},
|
||
|
|
];
|
||
|
|
testETCTextures(tests);
|
||
|
|
}
|
||
|
|
|
||
|
|
function testETCTextures(tests) {
|
||
|
|
for (var ii = 0; ii < tests.length; ++ii) {
|
||
|
|
testETCTexture(tests[ii]);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/* Return the size of block in bytes */
|
||
|
|
function getBlockSize(format) {
|
||
|
|
switch (format) {
|
||
|
|
case ext.COMPRESSED_R11_EAC:
|
||
|
|
case ext.COMPRESSED_SIGNED_R11_EAC:
|
||
|
|
case ext.COMPRESSED_RGB8_ETC2:
|
||
|
|
case ext.COMPRESSED_SRGB8_ETC2:
|
||
|
|
case ext.COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
|
||
|
|
case ext.COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
|
||
|
|
return 8;
|
||
|
|
case ext.COMPRESSED_RG11_EAC:
|
||
|
|
case ext.COMPRESSED_SIGNED_RG11_EAC:
|
||
|
|
case ext.COMPRESSED_RGBA8_ETC2_EAC:
|
||
|
|
case ext.COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
|
||
|
|
return 16
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
function copyRect(data, srcX, srcY, dstX, dstY, width, height, stride) {
|
||
|
|
var bytesPerLine = width * 4;
|
||
|
|
var srcOffset = srcX * 4 + srcY * stride;
|
||
|
|
var dstOffset = dstX * 4 + dstY * stride;
|
||
|
|
for (var jj = height; jj > 0; --jj) {
|
||
|
|
for (var ii = 0; ii < bytesPerLine; ++ii) {
|
||
|
|
data[dstOffset + ii] = data[srcOffset + ii];
|
||
|
|
}
|
||
|
|
srcOffset += stride;
|
||
|
|
dstOffset += stride;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
function testETCTexture(test) {
|
||
|
|
var data = new Uint8Array(test.data.compressed);
|
||
|
|
var width = test.width;
|
||
|
|
var height = test.height;
|
||
|
|
var format = test.format;
|
||
|
|
|
||
|
|
var uncompressedData = new Uint8Array(test.data.decompressed);
|
||
|
|
var glErrorShouldBe = (gl, glError, msg) => {
|
||
|
|
msg = msg || "";
|
||
|
|
var err = gl.getError();
|
||
|
|
var getGLErrorAsString = err => {
|
||
|
|
if (err === gl.NO_ERROR) {
|
||
|
|
return "NO_ERROR";
|
||
|
|
}
|
||
|
|
for (var name in gl) {
|
||
|
|
if (gl[name] === err) {
|
||
|
|
return name;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return err.toString();
|
||
|
|
}
|
||
|
|
|
||
|
|
if (err != glError) {
|
||
|
|
ok(false, "getError expected: " + getGLErrorAsString(glError) +
|
||
|
|
". Was " + getGLErrorAsString(err) + " : " + msg);
|
||
|
|
} else {
|
||
|
|
ok(true, "getError was expected value: " +
|
||
|
|
getGLErrorAsString(glError) + " : " + msg);
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
canvas.width = width;
|
||
|
|
canvas.height = height;
|
||
|
|
gl.viewport(0, 0, width, 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);
|
||
|
|
gl.compressedTexImage2D(gl.TEXTURE_2D, 0, format, width, height, 0, data);
|
||
|
|
glErrorShouldBe(gl, gl.NO_ERROR, "uploading compressed texture");
|
||
|
|
gl.generateMipmap(gl.TEXTURE_2D);
|
||
|
|
glErrorShouldBe(gl, gl.INVALID_OPERATION, "trying to generate mipmaps from compressed texture");
|
||
|
|
if (format == ext.COMPRESSED_SIGNED_R11_EAC) {
|
||
|
|
var program = WebGLUtil.createProgramByIds(gl, 'vshader', 'fshader-r');
|
||
|
|
} else if (format == ext.COMPRESSED_SIGNED_RG11_EAC) {
|
||
|
|
var program = WebGLUtil.createProgramByIds(gl, 'vshader', 'fshader-rg');
|
||
|
|
} else {
|
||
|
|
var program = WebGLUtil.createProgramByIds(gl, 'vshader', 'fshader');
|
||
|
|
}
|
||
|
|
gl.bindAttribLocation(program, 0, 'vPosition');
|
||
|
|
gl.bindAttribLocation(program, 1, 'texCoord0');
|
||
|
|
gl.useProgram(program);
|
||
|
|
|
||
|
|
gl.clearColor(1.0, 1.0, 1.0, 1.0);
|
||
|
|
gl.clear(gl.COLOR_BUFFER_BIT);
|
||
|
|
gl.drawArrays(gl.TRIANGLES, 0, 6);
|
||
|
|
compareRect(width, height, test.channels, width, height, uncompressedData, data, format);
|
||
|
|
|
||
|
|
gl.compressedTexImage2D(gl.TEXTURE_2D, 0, format, width, height, 1, data);
|
||
|
|
glErrorShouldBe(gl, gl.INVALID_VALUE, "non 0 border");
|
||
|
|
|
||
|
|
gl.compressedTexImage2D(gl.TEXTURE_2D, 0, format, width + 4, height, 0, data);
|
||
|
|
glErrorShouldBe(gl, gl.INVALID_VALUE, "data size does not match dimensions");
|
||
|
|
gl.compressedTexImage2D(gl.TEXTURE_2D, 0, format, width, height + 4, 0, data);
|
||
|
|
glErrorShouldBe(gl, gl.INVALID_VALUE, "data size does not match dimensions");
|
||
|
|
gl.compressedTexImage2D(gl.TEXTURE_2D, 0, format, width - 4, height, 0, data);
|
||
|
|
glErrorShouldBe(gl, gl.INVALID_VALUE, "data size does not match dimensions");
|
||
|
|
gl.compressedTexImage2D(gl.TEXTURE_2D, 0, format, width, height - 4, 0, data);
|
||
|
|
glErrorShouldBe(gl, gl.INVALID_VALUE, "data size does not match dimensions");
|
||
|
|
|
||
|
|
gl.compressedTexImage2D(gl.TEXTURE_2D, 0, format, width - 1, height, 0, data);
|
||
|
|
glErrorShouldBe(gl, gl.NO_ERROR, "non multiple-of-4 supported");
|
||
|
|
gl.compressedTexImage2D(gl.TEXTURE_2D, 0, format, width - 2, height, 0, data);
|
||
|
|
glErrorShouldBe(gl, gl.NO_ERROR, "non multiple-of-4 supported");
|
||
|
|
gl.compressedTexImage2D(gl.TEXTURE_2D, 0, format, width, height - 1, 0, data);
|
||
|
|
glErrorShouldBe(gl, gl.NO_ERROR, "non multiple-of-4 supported");
|
||
|
|
gl.compressedTexImage2D(gl.TEXTURE_2D, 0, format, width, height - 2, 0, data);
|
||
|
|
glErrorShouldBe(gl, gl.NO_ERROR, "non multiple-of-4 supported");
|
||
|
|
|
||
|
|
if (width == 4) {
|
||
|
|
gl.compressedTexImage2D(gl.TEXTURE_2D, 1, format, 1, height, 0, data);
|
||
|
|
glErrorShouldBe(gl, gl.NO_ERROR, "valid dimensions for level > 0");
|
||
|
|
gl.compressedTexImage2D(gl.TEXTURE_2D, 1, format, 2, height, 0, data);
|
||
|
|
glErrorShouldBe(gl, gl.NO_ERROR, "valid dimensions for level > 0");
|
||
|
|
}
|
||
|
|
if (height == 4) {
|
||
|
|
gl.compressedTexImage2D(gl.TEXTURE_2D, 1, format, width, 1, 0, data);
|
||
|
|
glErrorShouldBe(gl, gl.NO_ERROR, "valid dimensions for level > 0");
|
||
|
|
gl.compressedTexImage2D(gl.TEXTURE_2D, 1, format, width, 2, 0, data);
|
||
|
|
glErrorShouldBe(gl, gl.NO_ERROR, "valid dimensions for level > 0");
|
||
|
|
}
|
||
|
|
|
||
|
|
// pick a wrong format that uses the same amount of data.
|
||
|
|
var wrongFormat;
|
||
|
|
switch (format) {
|
||
|
|
case ext.COMPRESSED_R11_EAC:
|
||
|
|
wrongFormat = ext.COMPRESSED_SIGNED_R11_EAC;
|
||
|
|
break;
|
||
|
|
case ext.COMPRESSED_SIGNED_R11_EAC:
|
||
|
|
wrongFormat = ext.COMPRESSED_R11_EAC;
|
||
|
|
break;
|
||
|
|
case ext.COMPRESSED_RG11_EAC:
|
||
|
|
wrongFormat = ext.COMPRESSED_SIGNED_RG11_EAC;
|
||
|
|
break;
|
||
|
|
case ext.COMPRESSED_SIGNED_RG11_EAC:
|
||
|
|
wrongFormat = ext.COMPRESSED_RG11_EAC;
|
||
|
|
break;
|
||
|
|
case ext.COMPRESSED_RGB8_ETC2:
|
||
|
|
wrongFormat = ext.COMPRESSED_SRGB8_ETC2;
|
||
|
|
break;
|
||
|
|
case ext.COMPRESSED_SRGB8_ETC2:
|
||
|
|
wrongFormat = ext.COMPRESSED_RGB8_ETC2;
|
||
|
|
break;
|
||
|
|
case ext.COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
|
||
|
|
wrongFormat = ext.COMPRESSED_RGB8_ETC2;
|
||
|
|
break;
|
||
|
|
case ext.COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
|
||
|
|
wrongFormat = ext.COMPRESSED_RGB8_ETC2;
|
||
|
|
break;
|
||
|
|
case ext.COMPRESSED_RGBA8_ETC2_EAC:
|
||
|
|
wrongFormat = ext.COMPRESSED_SRGB8_ALPHA8_ETC2_EAC;
|
||
|
|
break;
|
||
|
|
case ext.COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
|
||
|
|
wrongFormat = ext.COMPRESSED_RGBA8_ETC2_EAC;
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
|
||
|
|
// Restore original texture.
|
||
|
|
gl.compressedTexImage2D(gl.TEXTURE_2D, 0, format, width, height, 0, data);
|
||
|
|
glErrorShouldBe(gl, gl.NO_ERROR, "uploading compressed texture");
|
||
|
|
|
||
|
|
gl.compressedTexSubImage2D(gl.TEXTURE_2D, 0, 0, 0, width, height, wrongFormat, data);
|
||
|
|
glErrorShouldBe(gl, gl.INVALID_OPERATION, "format does not match");
|
||
|
|
|
||
|
|
gl.compressedTexSubImage2D(gl.TEXTURE_2D, 0, 0, 0, width + 4, height, format, data);
|
||
|
|
glErrorShouldBe(gl, gl.INVALID_VALUE, "data size does not match dimensions");
|
||
|
|
gl.compressedTexSubImage2D(gl.TEXTURE_2D, 0, 0, 0, width, height + 4, format, data);
|
||
|
|
glErrorShouldBe(gl, gl.INVALID_VALUE, "data size does not match dimensions");
|
||
|
|
gl.compressedTexSubImage2D(gl.TEXTURE_2D, 0, 0, 0, width - 4, height, format, data);
|
||
|
|
glErrorShouldBe(gl, gl.INVALID_VALUE, "data size does not match dimensions");
|
||
|
|
gl.compressedTexSubImage2D(gl.TEXTURE_2D, 0, 0, 0, width, height - 4, format, data);
|
||
|
|
glErrorShouldBe(gl, gl.INVALID_VALUE, "data size does not match dimensions");
|
||
|
|
|
||
|
|
gl.compressedTexImage2D(gl.TEXTURE_2D, 0, format, width, height, 0, data);
|
||
|
|
glErrorShouldBe(gl, gl.NO_ERROR, "uploading compressed texture");
|
||
|
|
gl.compressedTexSubImage2D(gl.TEXTURE_2D, 0, 0, 0, width - 1, height, format, data);
|
||
|
|
glErrorShouldBe(gl, gl.INVALID_OPERATION, "invalid dimensions");
|
||
|
|
gl.compressedTexSubImage2D(gl.TEXTURE_2D, 0, 0, 0, width - 2, height, format, data);
|
||
|
|
glErrorShouldBe(gl, gl.INVALID_OPERATION, "invalid dimensions");
|
||
|
|
gl.compressedTexSubImage2D(gl.TEXTURE_2D, 0, 0, 0, width, height - 1, format, data);
|
||
|
|
glErrorShouldBe(gl, gl.INVALID_OPERATION, "invalid dimensions");
|
||
|
|
gl.compressedTexSubImage2D(gl.TEXTURE_2D, 0, 0, 0, width, height - 2, format, data);
|
||
|
|
glErrorShouldBe(gl, gl.INVALID_OPERATION, "invalid dimensions");
|
||
|
|
|
||
|
|
var subData = new Uint8Array(data.buffer, 0, getBlockSize(format));
|
||
|
|
|
||
|
|
if (width == 8 && height == 8) {
|
||
|
|
gl.compressedTexSubImage2D(gl.TEXTURE_2D, 0, 1, 0, 4, 4, format, subData);
|
||
|
|
glErrorShouldBe(gl, gl.INVALID_OPERATION, "invalid offset");
|
||
|
|
gl.compressedTexSubImage2D(gl.TEXTURE_2D, 0, 0, 1, 4, 4, format, subData);
|
||
|
|
glErrorShouldBe(gl, gl.INVALID_OPERATION, "invalid offset");
|
||
|
|
}
|
||
|
|
|
||
|
|
if (width < 32 && height < 32) {
|
||
|
|
var stride = width * 4;
|
||
|
|
for (var yoff = 0; yoff < height; yoff += 4) {
|
||
|
|
for (var xoff = 0; xoff < width; xoff += 4) {
|
||
|
|
copyRect(uncompressedData, 0, 0, xoff, yoff, 4, 4, stride);
|
||
|
|
gl.compressedTexSubImage2D(gl.TEXTURE_2D, 0, xoff, yoff, 4, 4, format, subData);
|
||
|
|
glErrorShouldBe(gl, gl.NO_ERROR, "uploading compressed texture");
|
||
|
|
gl.clearColor(1.0, 1.0, 1.0, 1.0);
|
||
|
|
gl.clear(gl.COLOR_BUFFER_BIT);
|
||
|
|
gl.drawArrays(gl.TRIANGLES, 0, 6);
|
||
|
|
compareRect(width, height, test.channels, width, height, uncompressedData, data, format);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
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 convertToSRGB(val) {
|
||
|
|
var norm = val / 255.0;
|
||
|
|
var res = 0;
|
||
|
|
if (norm <= 0.04045) {
|
||
|
|
res = norm / 12.92;
|
||
|
|
} else {
|
||
|
|
res = Math.pow(((norm + 0.055)/1.055), 2.4);
|
||
|
|
}
|
||
|
|
|
||
|
|
return res * 255.0;
|
||
|
|
}
|
||
|
|
|
||
|
|
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 < imageHeight; ++yy) {
|
||
|
|
for (var xx = 0; xx < imageWidth; ++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";
|
||
|
|
var hasAlpha = actualChannels == 4;
|
||
|
|
var imgExpected = makeImage(actualWidth, actualHeight, dataWidth, expectedData, hasAlpha);
|
||
|
|
var imgActual = makeImage(actualWidth, actualHeight, actualWidth, actual, hasAlpha);
|
||
|
|
insertImg(div, "expected", imgExpected);
|
||
|
|
insertImg(div, "actual", imgActual);
|
||
|
|
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.slice(expectedOffset, expectedOffset + 4);
|
||
|
|
|
||
|
|
var maxDiffPixel = 0;
|
||
|
|
switch (testFormat) {
|
||
|
|
case ext.COMPRESSED_SRGB8_ETC2:
|
||
|
|
case ext.COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
|
||
|
|
case ext.COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
|
||
|
|
|
||
|
|
// Alpha shouldn't do conversion.
|
||
|
|
for (var i = 0; i < 3; ++i) {
|
||
|
|
expected[i] = convertToSRGB(expected[i]);
|
||
|
|
}
|
||
|
|
//fallthrough
|
||
|
|
case ext.COMPRESSED_R11_EAC:
|
||
|
|
case ext.COMPRESSED_RG11_EAC:
|
||
|
|
case ext.COMPRESSED_SIGNED_R11_EAC:
|
||
|
|
case ext.COMPRESSED_SIGNED_RG11_EAC:
|
||
|
|
// Due to floating round error, we need fuzzy test here.
|
||
|
|
var maxDiffPixel = 1;
|
||
|
|
break;
|
||
|
|
default:
|
||
|
|
var maxDiffPixel = 0;
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
|
||
|
|
for (var channel = 0; channel < actualChannels; ++channel) {
|
||
|
|
var diff = Math.abs(expected[channel] - actual[actualOffset + channel]);
|
||
|
|
|
||
|
|
if (diff > maxDiffPixel) {
|
||
|
|
failed = true;
|
||
|
|
var was = actual.slice(actualOffset, actualOffset + 4).join();
|
||
|
|
ok(false, 'at (' + xx + ', ' + yy +
|
||
|
|
') expected: ' + expected.join() + ' was ' + was);
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
if (!failed) {
|
||
|
|
ok(true, "texture rendered correctly");
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
var prefArrArr = [
|
||
|
|
['webgl.enable-draft-extensions', true],
|
||
|
|
];
|
||
|
|
var prefEnv = {'set': prefArrArr};
|
||
|
|
SimpleTest.waitForExplicitFinish();
|
||
|
|
SpecialPowers.pushPrefEnv(prefEnv, runTest);
|
||
|
|
</script>
|
||
|
|
</body>
|
||
|
|
</html>
|