tex-image-and-sub-image-with-array-buffer-view-sub-source.html (7974B)
1 <!-- 2 Copyright (c) 2019 The Khronos Group Inc. 3 Use of this source code is governed by an MIT-style license that can be 4 found in the LICENSE.txt file. 5 --> 6 7 <!DOCTYPE html> 8 <html> 9 <head> 10 <meta charset="utf-8"> 11 <link rel="stylesheet" href="../../../resources/js-test-style.css"/> 12 <script src="../../../js/js-test-pre.js"></script> 13 <script src="../../../js/webgl-test-utils.js"></script> 14 <script src="../../../js/tests/tex-image-and-sub-image-utils.js"></script> 15 </head> 16 <body> 17 <canvas id="example" width="2" height="2"></canvas> 18 <div id="description"></div> 19 <div id="console"></div> 20 <script> 21 "use strict"; 22 description('Verifies tex{Sub}Image{2|3}D code paths taking partial ArrayBufferView'); 23 24 var wtu = WebGLTestUtils; 25 var tiu = TexImageUtils; 26 27 function createSource(width, height, depth, viewType, offset) { 28 var size = width * height * depth * 4; // RGBA 29 var buf = new window[viewType](size + offset); 30 for (var ii = 0; ii < size; ++ii) { 31 if (viewType == "Float32Array") 32 buf[ii + offset] = ii / 255.0; 33 else 34 buf[ii + offset] = ii; 35 } 36 return buf; 37 } 38 39 function comparePixels(ref, refOffset, data, tol) { 40 for (var ii = 0; ii < data.length; ++ii) { 41 // Skip alpha due to shader's handling of alpha values. 42 if (ii % 4 == 3) 43 continue; 44 var src = ref[ii + refOffset]; 45 if (ref instanceof Float32Array) 46 src *= 255; 47 if (Math.abs(src - data[ii]) > tol) { 48 testFailed("Element " + ii + ": expected " + src + ", got " + data[ii]); 49 return; 50 } 51 } 52 return testPassed("texture data uploaded correctly"); 53 } 54 55 function run2DTest(gl, test, width, height, srcOffset, tol) { 56 debug(""); 57 debug("Tesing tex{Sub}Image2D with sub source: internalformat = " + test.internalformat + 58 ", format = " + test.format + ", type = " + test.type); 59 60 var program = tiu.setupTexturedQuad(gl, test.internalformat); 61 if (!program) { 62 testFailed("Failed to set up program"); 63 return; 64 } 65 66 var buf = createSource(width, height, 1, test.viewType, srcOffset); 67 68 var texture = gl.createTexture(); 69 gl.bindTexture(gl.TEXTURE_2D, texture); 70 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); 71 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); 72 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); 73 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); 74 gl.texImage2D(gl.TEXTURE_2D, 0, gl[test.internalformat], width, height, 0, 75 gl[test.format], gl[test.type], buf, srcOffset + 1); 76 wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "srcOffset too large"); 77 gl.texImage2D(gl.TEXTURE_2D, 0, gl[test.internalformat], width, height, 0, 78 gl[test.format], gl[test.type], buf, srcOffset); 79 wtu.glErrorShouldBe(gl, gl.NO_ERROR, "texImage2D succeeds with correct buffer and srcOffset"); 80 81 wtu.clearAndDrawUnitQuad(gl, [0, 0, 0, 255]); 82 var readBuf = new Uint8Array(width * height * 4); 83 gl.bindFramebuffer(gl.FRAMEBUFFER, null); 84 gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, readBuf); 85 wtu.glErrorShouldBe(gl, gl.NO_ERROR, "no error"); 86 var tol = 0.5; 87 comparePixels(buf, srcOffset, readBuf, tol); 88 89 gl.texImage2D(gl.TEXTURE_2D, 0, gl[test.internalformat], width, height, 0, 90 gl[test.format], gl[test.type], null); 91 gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, width, height, gl[test.format], gl[test.type], 92 buf, srcOffset + 1); 93 wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "srcOffset too large"); 94 gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, width, height, gl[test.format], gl[test.type], 95 buf, srcOffset); 96 wtu.glErrorShouldBe(gl, gl.NO_ERROR, "texSubImage2D succeeds with correct buffer and srcOffset"); 97 98 wtu.clearAndDrawUnitQuad(gl, [0, 0, 0, 255]); 99 gl.bindFramebuffer(gl.FRAMEBUFFER, null); 100 gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, readBuf); 101 wtu.glErrorShouldBe(gl, gl.NO_ERROR, "no error"); 102 comparePixels(buf, srcOffset, readBuf, tol); 103 104 gl.deleteTexture(texture); 105 gl.deleteProgram(program); 106 } 107 108 function run3DTest(gl, test, width, height, srcOffset, tol) { 109 debug(""); 110 debug("Tesing tex{Sub}Image3D with sub source: internalformat = " + test.internalformat + 111 ", format = " + test.format + ", type = " + test.type); 112 113 var program = tiu.setupTexturedQuadWith3D(gl, test.internalformat); 114 if (!program) { 115 testFailed("Failed to set up program"); 116 return; 117 } 118 119 var depth = 1; 120 var buf = createSource(width, height, depth, test.viewType, srcOffset); 121 122 var texture = gl.createTexture(); 123 gl.bindTexture(gl.TEXTURE_3D, texture); 124 gl.texParameteri(gl.TEXTURE_3D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); 125 gl.texParameteri(gl.TEXTURE_3D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); 126 gl.texParameteri(gl.TEXTURE_3D, gl.TEXTURE_WRAP_R, gl.CLAMP_TO_EDGE); 127 gl.texParameteri(gl.TEXTURE_3D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); 128 gl.texParameteri(gl.TEXTURE_3D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); 129 gl.texImage3D(gl.TEXTURE_3D, 0, gl[test.internalformat], width, height, depth, 0, 130 gl[test.format], gl[test.type], buf, srcOffset + 1); 131 wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "srcOffset too large"); 132 gl.texImage3D(gl.TEXTURE_3D, 0, gl[test.internalformat], width, height, depth, 0, 133 gl[test.format], gl[test.type], buf, srcOffset); 134 wtu.glErrorShouldBe(gl, gl.NO_ERROR, "texImage3D succeeds with correct buffer and srcOffset"); 135 136 wtu.clearAndDrawUnitQuad(gl, [0, 0, 0, 255]); 137 var readBuf = new Uint8Array(width * height * 4); 138 gl.bindFramebuffer(gl.FRAMEBUFFER, null); 139 gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, readBuf); 140 wtu.glErrorShouldBe(gl, gl.NO_ERROR, "no error"); 141 var tol = 0.5; 142 comparePixels(buf, srcOffset, readBuf, tol); 143 144 gl.texImage3D(gl.TEXTURE_3D, 0, gl[test.internalformat], width, height, depth, 0, 145 gl[test.format], gl[test.type], null); 146 gl.texSubImage3D(gl.TEXTURE_3D, 0, 0, 0, 0, width, height, depth, gl[test.format], gl[test.type], 147 buf, srcOffset + 1); 148 wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "srcOffset too large"); 149 gl.texSubImage3D(gl.TEXTURE_3D, 0, 0, 0, 0, width, height, depth, gl[test.format], gl[test.type], 150 buf, srcOffset); 151 wtu.glErrorShouldBe(gl, gl.NO_ERROR, "texSubImage3D succeeds with correct buffer and srcOffset"); 152 153 wtu.clearAndDrawUnitQuad(gl, [0, 0, 0, 255]); 154 gl.bindFramebuffer(gl.FRAMEBUFFER, null); 155 gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, readBuf); 156 wtu.glErrorShouldBe(gl, gl.NO_ERROR, "no error"); 157 comparePixels(buf, srcOffset, readBuf, tol); 158 159 gl.deleteTexture(texture); 160 gl.deleteProgram(program); 161 } 162 163 var gl = wtu.create3DContext("example", undefined, 2); 164 if (!gl) { 165 testFailed("Fail to get a WebGL context"); 166 } else { 167 var testCases = [ 168 { internalformat: 'RGBA8', format: 'RGBA', type: 'UNSIGNED_BYTE', 169 viewType: 'Uint8Array', }, 170 { internalformat: 'RGBA8I', format: 'RGBA_INTEGER', type: 'BYTE', 171 viewType: 'Int8Array', }, 172 { internalformat: 'RGBA16UI', format: 'RGBA_INTEGER', type: 'UNSIGNED_SHORT', 173 viewType: 'Uint16Array', }, 174 { internalformat: 'RGBA16I', format: 'RGBA_INTEGER', type: 'SHORT', 175 viewType: 'Int16Array', }, 176 { internalformat: 'RGBA32UI', format: 'RGBA_INTEGER', type: 'UNSIGNED_INT', 177 viewType: 'Uint32Array', }, 178 { internalformat: 'RGBA32I', format: 'RGBA_INTEGER', type: 'INT', 179 viewType: 'Int32Array', }, 180 { internalformat: 'RGBA32F', format: 'RGBA', type: 'FLOAT', 181 viewType: 'Float32Array', }, 182 ]; 183 184 var srcOffset = 3; 185 var tol = 0.5; 186 187 for (var idx = 0; idx < testCases.length; ++idx) { 188 run2DTest(gl, testCases[idx], gl.drawingBufferWidth, gl.drawingBufferHeight, srcOffset, tol); 189 run3DTest(gl, testCases[idx], gl.drawingBufferWidth, gl.drawingBufferHeight, srcOffset, tol); 190 } 191 } 192 193 var successfullyParsed = true; 194 </script> 195 <script src="../../../js/js-test-post.js"></script> 196 </body> 197 </html>