| <!-- |
| 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) { |
| let pixelValue; |
| let expectedValue; |
| let imageData; |
| |
| switch(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, internalFormat, 1, 1, 0, format, type, imageData); |
| |
| wtu.glErrorShouldBe(gl, gl.NO_ERROR, "texture bindings succeed"); |
| |
| gl.drawArrays(gl.TRIANGLES, 0, 6); |
| |
| // Read back as gl.UNSIGNED_BYTE |
| wtu.checkCanvasRect(gl, 0, 0, 1, 1, generateFormatColor(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 testSnorm16Unrenderable(internalFormat, format, type) { |
| gl.bindTexture(gl.TEXTURE_2D, textures[1]); |
| gl.texImage2D(gl.TEXTURE_2D, 0, internalFormat, 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 SNORM16 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); |
| |
| testNorm16Texture(ext.R16_EXT, gl.RED, gl.UNSIGNED_SHORT); |
| testNorm16Texture(ext.RG16_EXT, gl.RG, gl.UNSIGNED_SHORT); |
| testNorm16Texture(ext.RGB16_EXT, gl.RGB, gl.UNSIGNED_SHORT); |
| testNorm16Texture(ext.RGBA16_EXT, gl.RGBA, gl.UNSIGNED_SHORT); |
| testNorm16Texture(ext.R16_SNORM_EXT, gl.RED, gl.SHORT); |
| testNorm16Texture(ext.RG16_SNORM_EXT, gl.RG, gl.SHORT); |
| testNorm16Texture(ext.RGB16_SNORM_EXT, gl.RGB, gl.SHORT); |
| testNorm16Texture(ext.RGBA16_SNORM_EXT, gl.RGBA, gl.SHORT); |
| |
| 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); |
| testNorm16Render(ext.RGBA16_EXT, gl.RGBA, gl.UNSIGNED_SHORT, 0); |
| |
| testSnorm16Unrenderable(ext.R16_SNORM_EXT, gl.RED, gl.SHORT); |
| testSnorm16Unrenderable(ext.RG16_SNORM_EXT, gl.RG, gl.SHORT); |
| testSnorm16Unrenderable(ext.RGB16_SNORM_EXT, gl.RGB, gl.SHORT); |
| testSnorm16Unrenderable(ext.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> |