Thu, 22 Jan 2015 13:21:57 +0100
Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6
michael@0 | 1 | <!-- |
michael@0 | 2 | Copyright (c) 2011 The Chromium Authors. All rights reserved. |
michael@0 | 3 | Use of this source code is governed by a BSD-style license that can be |
michael@0 | 4 | found in the LICENSE file. |
michael@0 | 5 | --> |
michael@0 | 6 | <!DOCTYPE html> |
michael@0 | 7 | <html> |
michael@0 | 8 | <head> |
michael@0 | 9 | <meta charset="utf-8"> |
michael@0 | 10 | <title>WebGL OES_texture_float Conformance Tests</title> |
michael@0 | 11 | <link rel="stylesheet" href="../../resources/js-test-style.css"/> |
michael@0 | 12 | <script src="../../resources/desktop-gl-constants.js" type="text/javascript"></script> |
michael@0 | 13 | <script src="../../resources/js-test-pre.js"></script> |
michael@0 | 14 | <script src="../resources/webgl-test.js"></script> |
michael@0 | 15 | <script src="../resources/webgl-test-utils.js"></script> |
michael@0 | 16 | </head> |
michael@0 | 17 | <body> |
michael@0 | 18 | <div id="description"></div> |
michael@0 | 19 | <canvas id="canvas" style="width: 50px; height: 50px;"> </canvas> |
michael@0 | 20 | <div id="console"></div> |
michael@0 | 21 | <!-- Shaders for testing floating-point textures --> |
michael@0 | 22 | <script id="testFragmentShader" type="x-shader/x-fragment"> |
michael@0 | 23 | precision mediump float; |
michael@0 | 24 | uniform sampler2D tex; |
michael@0 | 25 | varying vec2 texCoord; |
michael@0 | 26 | void main() |
michael@0 | 27 | { |
michael@0 | 28 | vec4 color = texture2D(tex, texCoord); |
michael@0 | 29 | if (abs(color.r - 10000.0) + |
michael@0 | 30 | abs(color.g - 10000.0) + |
michael@0 | 31 | abs(color.b - 10000.0) + |
michael@0 | 32 | abs(color.a - 10000.0) < 8.0) { |
michael@0 | 33 | gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0); |
michael@0 | 34 | } else { |
michael@0 | 35 | gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); |
michael@0 | 36 | } |
michael@0 | 37 | } |
michael@0 | 38 | </script> |
michael@0 | 39 | <!-- Shaders for testing floating-point render targets --> |
michael@0 | 40 | <script id="positionVertexShader" type="x-shader/x-vertex"> |
michael@0 | 41 | attribute vec4 vPosition; |
michael@0 | 42 | void main() |
michael@0 | 43 | { |
michael@0 | 44 | gl_Position = vPosition; |
michael@0 | 45 | } |
michael@0 | 46 | </script> |
michael@0 | 47 | <script id="floatingPointFragmentShader" type="x-shader/x-fragment"> |
michael@0 | 48 | void main() |
michael@0 | 49 | { |
michael@0 | 50 | gl_FragColor = vec4(10000.0, 10000.0, 10000.0, 10000.0); |
michael@0 | 51 | } |
michael@0 | 52 | </script> |
michael@0 | 53 | <script> |
michael@0 | 54 | description("This test verifies the functionality of the OES_texture_float extension, if it is available."); |
michael@0 | 55 | |
michael@0 | 56 | debug(""); |
michael@0 | 57 | |
michael@0 | 58 | var wtu = WebGLTestUtils; |
michael@0 | 59 | var canvas = document.getElementById("canvas"); |
michael@0 | 60 | var gl = create3DContext(canvas); |
michael@0 | 61 | |
michael@0 | 62 | if (!gl) { |
michael@0 | 63 | testFailed("WebGL context does not exist"); |
michael@0 | 64 | } else { |
michael@0 | 65 | testPassed("WebGL context exists"); |
michael@0 | 66 | |
michael@0 | 67 | var texturedShaders = [ |
michael@0 | 68 | wtu.setupSimpleTextureVertexShader(gl), |
michael@0 | 69 | "testFragmentShader" |
michael@0 | 70 | ]; |
michael@0 | 71 | var testProgram = |
michael@0 | 72 | wtu.setupProgram(gl, |
michael@0 | 73 | texturedShaders, |
michael@0 | 74 | ['vPosition', 'texCoord0'], |
michael@0 | 75 | [0, 1]); |
michael@0 | 76 | var quadParameters = wtu.setupUnitQuad(gl, 0, 1); |
michael@0 | 77 | |
michael@0 | 78 | // First verify that allocation of floating-point textures fails if |
michael@0 | 79 | // the extension has not been enabled yet. |
michael@0 | 80 | runTextureCreationTest(testProgram, false); |
michael@0 | 81 | |
michael@0 | 82 | if (!gl.getExtension("OES_texture_float")) { |
michael@0 | 83 | testPassed("No OES_texture_float support -- this is legal"); |
michael@0 | 84 | } else { |
michael@0 | 85 | testPassed("Successfully enabled OES_texture_float extension"); |
michael@0 | 86 | runTextureCreationTest(testProgram, true); |
michael@0 | 87 | runRenderTargetTest(testProgram); |
michael@0 | 88 | runUniqueObjectTest(); |
michael@0 | 89 | runReferenceCycleTest(); |
michael@0 | 90 | } |
michael@0 | 91 | } |
michael@0 | 92 | |
michael@0 | 93 | // Needs to be global for shouldBe to see it. |
michael@0 | 94 | var pixels; |
michael@0 | 95 | |
michael@0 | 96 | function allocateTexture() |
michael@0 | 97 | { |
michael@0 | 98 | var texture = gl.createTexture(); |
michael@0 | 99 | gl.bindTexture(gl.TEXTURE_2D, texture); |
michael@0 | 100 | gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); |
michael@0 | 101 | gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); |
michael@0 | 102 | gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); |
michael@0 | 103 | gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); |
michael@0 | 104 | glErrorShouldBe(gl, gl.NO_ERROR, "texture parameter setup should succeed"); |
michael@0 | 105 | return texture; |
michael@0 | 106 | } |
michael@0 | 107 | |
michael@0 | 108 | function checkRenderingResults() |
michael@0 | 109 | { |
michael@0 | 110 | pixels = new Uint8Array(4); |
michael@0 | 111 | gl.readPixels(0, 0, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, pixels); |
michael@0 | 112 | // Outputs green if OK, red if not. |
michael@0 | 113 | shouldBe("pixels[0]", "0"); |
michael@0 | 114 | shouldBe("pixels[1]", "255"); |
michael@0 | 115 | shouldBe("pixels[2]", "0"); |
michael@0 | 116 | shouldBe("pixels[3]", "255"); |
michael@0 | 117 | } |
michael@0 | 118 | |
michael@0 | 119 | function runTextureCreationTest(testProgram, extensionEnabled) |
michael@0 | 120 | { |
michael@0 | 121 | var expectFailure = !extensionEnabled; |
michael@0 | 122 | |
michael@0 | 123 | var texture = allocateTexture(); |
michael@0 | 124 | // Generate data. |
michael@0 | 125 | var width = 2; |
michael@0 | 126 | var height = 2; |
michael@0 | 127 | var numberOfChannels = 4; |
michael@0 | 128 | var data = new Float32Array(width * height * numberOfChannels); |
michael@0 | 129 | for (var ii = 0; ii < data.length; ++ii) { |
michael@0 | 130 | data[ii] = 10000; |
michael@0 | 131 | } |
michael@0 | 132 | gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, width, height, 0, gl.RGBA, gl.FLOAT, data); |
michael@0 | 133 | if (expectFailure) { |
michael@0 | 134 | glErrorShouldBe(gl, gl.INVALID_ENUM, "floating-point texture allocation must be disallowed if OES_texture_float isn't enabled"); |
michael@0 | 135 | return; |
michael@0 | 136 | } else { |
michael@0 | 137 | glErrorShouldBe(gl, gl.NO_ERROR, "floating-point texture allocation should succeed if OES_texture_float is enabled"); |
michael@0 | 138 | } |
michael@0 | 139 | // Verify that the texture actually works for sampling and contains the expected data. |
michael@0 | 140 | gl.uniform1i(gl.getUniformLocation(testProgram, "tex"), 0); |
michael@0 | 141 | wtu.drawQuad(gl); |
michael@0 | 142 | checkRenderingResults(); |
michael@0 | 143 | } |
michael@0 | 144 | |
michael@0 | 145 | function runRenderTargetTest(testProgram) |
michael@0 | 146 | { |
michael@0 | 147 | var texture = allocateTexture(); |
michael@0 | 148 | var width = 2; |
michael@0 | 149 | var height = 2; |
michael@0 | 150 | var numberOfChannels = 4; |
michael@0 | 151 | gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, width, height, 0, gl.RGBA, gl.FLOAT, null); |
michael@0 | 152 | glErrorShouldBe(gl, gl.NO_ERROR, "floating-point texture allocation should succeed if OES_texture_float is enabled"); |
michael@0 | 153 | |
michael@0 | 154 | // Use this texture as a render target. |
michael@0 | 155 | var fbo = gl.createFramebuffer(); |
michael@0 | 156 | gl.bindFramebuffer(gl.FRAMEBUFFER, fbo); |
michael@0 | 157 | gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0); |
michael@0 | 158 | gl.bindTexture(gl.TEXTURE_2D, null); |
michael@0 | 159 | shouldBe("gl.checkFramebufferStatus(gl.FRAMEBUFFER)", "gl.FRAMEBUFFER_COMPLETE"); |
michael@0 | 160 | // While strictly speaking it is probably legal for a WebGL implementation to support |
michael@0 | 161 | // floating-point textures but not as attachments to framebuffer objects, any such |
michael@0 | 162 | // implementation is so poor that it arguably should not advertise support for the |
michael@0 | 163 | // OES_texture_float extension. For this reason the conformance test requires that the |
michael@0 | 164 | // framebuffer is complete here. |
michael@0 | 165 | if (gl.checkFramebufferStatus(gl.FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE) |
michael@0 | 166 | return; |
michael@0 | 167 | |
michael@0 | 168 | var renderProgram = |
michael@0 | 169 | wtu.setupProgram(gl, |
michael@0 | 170 | ["positionVertexShader", "floatingPointFragmentShader"], |
michael@0 | 171 | ['vPosition'], |
michael@0 | 172 | [0]); |
michael@0 | 173 | wtu.drawQuad(gl); |
michael@0 | 174 | glErrorShouldBe(gl, gl.NO_ERROR, "rendering to floating-point texture should succeed"); |
michael@0 | 175 | |
michael@0 | 176 | // Now sample from the floating-point texture and verify we got the correct values. |
michael@0 | 177 | gl.bindFramebuffer(gl.FRAMEBUFFER, null); |
michael@0 | 178 | gl.bindTexture(gl.TEXTURE_2D, texture); |
michael@0 | 179 | gl.useProgram(testProgram); |
michael@0 | 180 | gl.uniform1i(gl.getUniformLocation(testProgram, "tex"), 0); |
michael@0 | 181 | wtu.drawQuad(gl); |
michael@0 | 182 | glErrorShouldBe(gl, gl.NO_ERROR, "rendering from floating-point texture should succeed"); |
michael@0 | 183 | checkRenderingResults(); |
michael@0 | 184 | } |
michael@0 | 185 | |
michael@0 | 186 | function runUniqueObjectTest() |
michael@0 | 187 | { |
michael@0 | 188 | debug("Testing that getExtension() returns the same object each time"); |
michael@0 | 189 | gl.getExtension("OES_texture_float").myProperty = 2; |
michael@0 | 190 | gc(); |
michael@0 | 191 | shouldBe('gl.getExtension("OES_texture_float").myProperty', '2'); |
michael@0 | 192 | } |
michael@0 | 193 | |
michael@0 | 194 | function runReferenceCycleTest() |
michael@0 | 195 | { |
michael@0 | 196 | // create some reference cycles. The goal is to see if they cause leaks. The point is that |
michael@0 | 197 | // some browser test runners have instrumentation to detect leaked refcounted objects. |
michael@0 | 198 | |
michael@0 | 199 | debug("Testing reference cycles between context and extension objects"); |
michael@0 | 200 | var ext = gl.getExtension("OES_texture_float"); |
michael@0 | 201 | |
michael@0 | 202 | // create cycle between extension and context, since the context has to hold a reference to the extension |
michael@0 | 203 | ext.context = gl; |
michael@0 | 204 | |
michael@0 | 205 | // create a self-cycle on the extension object |
michael@0 | 206 | ext.ext = ext; |
michael@0 | 207 | } |
michael@0 | 208 | |
michael@0 | 209 | debug(""); |
michael@0 | 210 | successfullyParsed = true; |
michael@0 | 211 | </script> |
michael@0 | 212 | <script>finishTest();</script> |
michael@0 | 213 | |
michael@0 | 214 | </body> |
michael@0 | 215 | </html> |