Backed out changeset 7272b7396c78 (bug 1932758) for causing fenix debug failures...
[gecko.git] / dom / canvas / test / webgl-conf / checkout / conformance2 / rendering / framebuffer-render-to-layer.html
blobc34f2a41436bb63ba0674781ee91dbd0528af0e8
1 <!--
2 Copyright (c) 2020 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 -->
7 <!DOCTYPE html>
8 <html>
9 <head>
10 <meta charset="utf-8">
11 <title>WebGL2 can render to layers in 3D and 2D_ARRAY textures</title>
12 <link rel="stylesheet" href="../../resources/js-test-style.css"/>
13 <script src="../../js/js-test-pre.js"></script>
14 <script src="../../js/webgl-test-utils.js"></script>
15 <script id="vshader" type="x-shader/x-vertex">#version 300 es
16 void main(void) {
17 gl_Position = vec4(0, 0, 0, 1);
18 gl_PointSize = 1.0;
20 </script>
21 </head>
22 <body>
23 <canvas id="example" width="100", height="100"></canvas>
24 <div id="description"></div>
25 <div id="console"></div>
26 <script>
27 "use strict";
28 debug("");
30 description("Test that WebGL2 can render to layers in 3D and 2D_ARRAY textures");
32 var wtu = WebGLTestUtils;
33 var gl = wtu.create3DContext("example", undefined, 2);
35 if (!gl) {
36 testFailed("WebGL context creation failed");
37 } else {
38 testPassed("WebGL context creation succeeded");
39 runTest();
42 function runTest() {
43 const texWidth = 1;
44 const texHeight = 1;
45 const texDepth = 2;
47 function makeFragmentShader(typeInfo) {
48 const src = `#version 300 es
49 precision mediump float;
50 out ${typeInfo.outType} color;
51 void main() {
52 color = ${typeInfo.outValue};
55 return src;
58 const textureInternalFormatInfo = {};
60 const t = textureInternalFormatInfo;
61 // unsized formats
62 // If understand correctly these 3 unsized formats are not required to be color renderable
63 t[gl.ALPHA] = { textureFormat: gl.ALPHA, colorRenderable: false, textureFilterable: true, bytesPerElement: [1, 2, 2, 4], type: [gl.UNSIGNED_BYTE, gl.HALF_FLOAT, gl.HALF_FLOAT_OES, gl.FLOAT], };
64 t[gl.LUMINANCE] = { textureFormat: gl.LUMINANCE, colorRenderable: false, textureFilterable: true, bytesPerElement: [1, 2, 2, 4], type: [gl.UNSIGNED_BYTE, gl.HALF_FLOAT, gl.HALF_FLOAT_OES, gl.FLOAT], };
65 t[gl.LUMINANCE_ALPHA] = { textureFormat: gl.LUMINANCE_ALPHA, colorRenderable: false, textureFilterable: true, bytesPerElement: [2, 4, 4, 8], type: [gl.UNSIGNED_BYTE, gl.HALF_FLOAT, gl.HALF_FLOAT_OES, gl.FLOAT], };
67 t[gl.RGB] = { textureFormat: gl.RGB, colorRenderable: true, textureFilterable: true, bytesPerElement: [3, 6, 6, 12, 2], type: [gl.UNSIGNED_BYTE, gl.HALF_FLOAT, gl.HALF_FLOAT_OES, gl.FLOAT, gl.UNSIGNED_SHORT_5_6_5], };
68 t[gl.RGBA] = { textureFormat: gl.RGBA, colorRenderable: true, textureFilterable: true, bytesPerElement: [4, 8, 8, 16, 2, 2], type: [gl.UNSIGNED_BYTE, gl.HALF_FLOAT, gl.HALF_FLOAT_OES, gl.FLOAT, gl.UNSIGNED_SHORT_4_4_4_4, gl.UNSIGNED_SHORT_5_5_5_1], };
70 // sized formats
71 t[gl.R8] = { textureFormat: gl.RED, colorRenderable: true, textureFilterable: true, bytesPerElement: [1], type: [gl.UNSIGNED_BYTE], };
72 t[gl.R8_SNORM] = { textureFormat: gl.RED, colorRenderable: false, textureFilterable: true, bytesPerElement: [1], type: [gl.BYTE], };
73 t[gl.R16F] = { textureFormat: gl.RED, colorRenderable: false, textureFilterable: true, bytesPerElement: [4, 2], type: [gl.FLOAT, gl.HALF_FLOAT], };
74 t[gl.R32F] = { textureFormat: gl.RED, colorRenderable: false, textureFilterable: false, bytesPerElement: [4], type: [gl.FLOAT], };
75 t[gl.R8UI] = { textureFormat: gl.RED_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [1], type: [gl.UNSIGNED_BYTE], };
76 t[gl.R8I] = { textureFormat: gl.RED_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [1], type: [gl.BYTE], };
77 t[gl.R16UI] = { textureFormat: gl.RED_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [2], type: [gl.UNSIGNED_SHORT], };
78 t[gl.R16I] = { textureFormat: gl.RED_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [2], type: [gl.SHORT], };
79 t[gl.R32UI] = { textureFormat: gl.RED_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [4], type: [gl.UNSIGNED_INT], };
80 t[gl.R32I] = { textureFormat: gl.RED_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [4], type: [gl.INT], };
81 t[gl.RG8] = { textureFormat: gl.RG, colorRenderable: true, textureFilterable: true, bytesPerElement: [2], type: [gl.UNSIGNED_BYTE], };
82 t[gl.RG8_SNORM] = { textureFormat: gl.RG, colorRenderable: false, textureFilterable: true, bytesPerElement: [2], type: [gl.BYTE], };
83 t[gl.RG16F] = { textureFormat: gl.RG, colorRenderable: false, textureFilterable: true, bytesPerElement: [8, 4], type: [gl.FLOAT, gl.HALF_FLOAT], };
84 t[gl.RG32F] = { textureFormat: gl.RG, colorRenderable: false, textureFilterable: false, bytesPerElement: [8], type: [gl.FLOAT], };
85 t[gl.RG8UI] = { textureFormat: gl.RG_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [2], type: [gl.UNSIGNED_BYTE], };
86 t[gl.RG8I] = { textureFormat: gl.RG_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [2], type: [gl.BYTE], };
87 t[gl.RG16UI] = { textureFormat: gl.RG_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [4], type: [gl.UNSIGNED_SHORT], };
88 t[gl.RG16I] = { textureFormat: gl.RG_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [4], type: [gl.SHORT], };
89 t[gl.RG32UI] = { textureFormat: gl.RG_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [8], type: [gl.UNSIGNED_INT], };
90 t[gl.RG32I] = { textureFormat: gl.RG_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [8], type: [gl.INT], };
91 t[gl.RGB8] = { textureFormat: gl.RGB, colorRenderable: true, textureFilterable: true, bytesPerElement: [3], type: [gl.UNSIGNED_BYTE], };
92 t[gl.SRGB8] = { textureFormat: gl.RGB, colorRenderable: false, textureFilterable: true, bytesPerElement: [3], type: [gl.UNSIGNED_BYTE], };
93 t[gl.RGB565] = { textureFormat: gl.RGB, colorRenderable: true, textureFilterable: true, bytesPerElement: [3, 2], type: [gl.UNSIGNED_BYTE, gl.UNSIGNED_SHORT_5_6_5], };
94 t[gl.RGB8_SNORM] = { textureFormat: gl.RGB, colorRenderable: false, textureFilterable: true, bytesPerElement: [3], type: [gl.BYTE], };
95 t[gl.R11F_G11F_B10F] = { textureFormat: gl.RGB, colorRenderable: false, textureFilterable: true, bytesPerElement: [12, 6, 4], type: [gl.FLOAT, gl.HALF_FLOAT, gl.UNSIGNED_INT_10F_11F_11F_REV], };
96 t[gl.RGB9_E5] = { textureFormat: gl.RGB, colorRenderable: false, textureFilterable: true, bytesPerElement: [12, 6, 4], type: [gl.FLOAT, gl.HALF_FLOAT, gl.UNSIGNED_INT_5_9_9_9_REV], };
97 t[gl.RGB16F] = { textureFormat: gl.RGB, colorRenderable: false, textureFilterable: true, bytesPerElement: [12, 6], type: [gl.FLOAT, gl.HALF_FLOAT], };
98 t[gl.RGB32F] = { textureFormat: gl.RGB, colorRenderable: false, textureFilterable: false, bytesPerElement: [12], type: [gl.FLOAT], };
99 t[gl.RGB8UI] = { textureFormat: gl.RGB_INTEGER, colorRenderable: false, textureFilterable: false, bytesPerElement: [3], type: [gl.UNSIGNED_BYTE], };
100 t[gl.RGB8I] = { textureFormat: gl.RGB_INTEGER, colorRenderable: false, textureFilterable: false, bytesPerElement: [3], type: [gl.BYTE], };
101 t[gl.RGB16UI] = { textureFormat: gl.RGB_INTEGER, colorRenderable: false, textureFilterable: false, bytesPerElement: [6], type: [gl.UNSIGNED_SHORT], };
102 t[gl.RGB16I] = { textureFormat: gl.RGB_INTEGER, colorRenderable: false, textureFilterable: false, bytesPerElement: [6], type: [gl.SHORT], };
103 t[gl.RGB32UI] = { textureFormat: gl.RGB_INTEGER, colorRenderable: false, textureFilterable: false, bytesPerElement: [12], type: [gl.UNSIGNED_INT], };
104 t[gl.RGB32I] = { textureFormat: gl.RGB_INTEGER, colorRenderable: false, textureFilterable: false, bytesPerElement: [12], type: [gl.INT], };
105 t[gl.RGBA8] = { textureFormat: gl.RGBA, colorRenderable: true, textureFilterable: true, bytesPerElement: [4], type: [gl.UNSIGNED_BYTE], };
106 t[gl.SRGB8_ALPHA8] = { textureFormat: gl.RGBA, colorRenderable: true, textureFilterable: true, bytesPerElement: [4], type: [gl.UNSIGNED_BYTE], };
107 t[gl.RGBA8_SNORM] = { textureFormat: gl.RGBA, colorRenderable: false, textureFilterable: true, bytesPerElement: [4], type: [gl.BYTE], };
108 t[gl.RGB5_A1] = { textureFormat: gl.RGBA, colorRenderable: true, textureFilterable: true, bytesPerElement: [4, 2, 4], type: [gl.UNSIGNED_BYTE, gl.UNSIGNED_SHORT_5_5_5_1, gl.UNSIGNED_INT_2_10_10_10_REV], };
109 t[gl.RGBA4] = { textureFormat: gl.RGBA, colorRenderable: true, textureFilterable: true, bytesPerElement: [4, 2], type: [gl.UNSIGNED_BYTE, gl.UNSIGNED_SHORT_4_4_4_4], };
110 t[gl.RGB10_A2] = { textureFormat: gl.RGBA, colorRenderable: true, textureFilterable: true, bytesPerElement: [4], type: [gl.UNSIGNED_INT_2_10_10_10_REV], };
111 t[gl.RGBA16F] = { textureFormat: gl.RGBA, colorRenderable: false, textureFilterable: true, bytesPerElement: [16, 8], type: [gl.FLOAT, gl.HALF_FLOAT], };
112 t[gl.RGBA32F] = { textureFormat: gl.RGBA, colorRenderable: false, textureFilterable: false, bytesPerElement: [16], type: [gl.FLOAT], };
113 t[gl.RGBA8UI] = { textureFormat: gl.RGBA_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [4], type: [gl.UNSIGNED_BYTE], };
114 t[gl.RGBA8I] = { textureFormat: gl.RGBA_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [4], type: [gl.BYTE], };
115 t[gl.RGB10_A2UI] = { textureFormat: gl.RGBA_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [4], type: [gl.UNSIGNED_INT_2_10_10_10_REV], };
116 t[gl.RGBA16UI] = { textureFormat: gl.RGBA_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [8], type: [gl.UNSIGNED_SHORT], };
117 t[gl.RGBA16I] = { textureFormat: gl.RGBA_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [8], type: [gl.SHORT], };
118 t[gl.RGBA32I] = { textureFormat: gl.RGBA_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [16], type: [gl.INT], };
119 t[gl.RGBA32UI] = { textureFormat: gl.RGBA_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [16], type: [gl.UNSIGNED_INT], };
121 // Sized Internal
122 t[gl.DEPTH_COMPONENT16] = { textureFormat: gl.DEPTH_COMPONENT, colorRenderable: true, textureFilterable: false, bytesPerElement: [2, 4], type: [gl.UNSIGNED_SHORT, gl.UNSIGNED_INT], };
123 t[gl.DEPTH_COMPONENT24] = { textureFormat: gl.DEPTH_COMPONENT, colorRenderable: true, textureFilterable: false, bytesPerElement: [4], type: [gl.UNSIGNED_INT], };
124 t[gl.DEPTH_COMPONENT32F] = { textureFormat: gl.DEPTH_COMPONENT, colorRenderable: true, textureFilterable: false, bytesPerElement: [4], type: [gl.FLOAT], };
125 t[gl.DEPTH24_STENCIL8] = { textureFormat: gl.DEPTH_STENCIL, colorRenderable: true, textureFilterable: false, bytesPerElement: [4], type: [gl.UNSIGNED_INT_24_8], };
126 t[gl.DEPTH32F_STENCIL8] = { textureFormat: gl.DEPTH_STENCIL, colorRenderable: true, textureFilterable: false, bytesPerElement: [4], type: [gl.FLOAT_32_UNSIGNED_INT_24_8_REV], };
128 Object.keys(t).forEach(function(internalFormat) {
129 const info = t[internalFormat];
130 info.bytesPerElementMap = {};
131 info.bytesPerElement.forEach(function(bytesPerElement, ndx) {
132 const type = info.type[ndx];
133 info.bytesPerElementMap[type] = bytesPerElement;
138 const validChannelsByTextureFormat = {};
140 const v = validChannelsByTextureFormat;
141 v[gl.RED] = [1, 0, 0, 0];
142 v[gl.RG] = [1, 1, 0, 0];
143 v[gl.RGB] = [1, 1, 1, 0];
144 v[gl.RGBA] = [1, 1, 1, 1];
145 v[gl.RED_INTEGER] = [1, 0, 0, 0];
146 v[gl.RG_INTEGER] = [1, 1, 0, 0];
147 v[gl.RGB_INTEGER] = [1, 1, 1, 0];
148 v[gl.RGBA_INTEGER] = [1, 1, 1, 1];
151 const depthTextureFormats = [
152 gl.DEPTH_COMPONENT16,
153 gl.DEPTH_COMPONENT24,
154 gl.DEPTH_COMPONENT32F,
155 gl.DEPTH24_STENCIL8,
156 gl.DEPTH32F_STENCIL8,
159 const intTextureFormats = [
160 gl.R8I,
161 gl.R16I,
162 gl.R32I,
163 gl.RG8I,
164 gl.RG16I,
165 gl.RG32I,
166 gl.RGB8I,
167 gl.RGB16I,
168 gl.RGB32I,
169 gl.RGBA8I,
170 gl.RGBA16I,
171 gl.RGBA32I,
174 const unsignedIntTextureFormats = [
175 gl.R8UI,
176 gl.R16UI,
177 gl.R32UI,
178 gl.RG8UI,
179 gl.RG16UI,
180 gl.RG32UI,
181 gl.RGB8UI,
182 gl.RGB16UI,
183 gl.RGB32UI,
184 gl.RGBA8UI,
185 gl.RGB10_A2UI,
186 gl.RGBA16UI,
187 gl.RGBA32UI,
190 const floatTextureFormats = Object.keys(textureInternalFormatInfo).map(function(v) {
191 return parseInt(v);
192 }).filter(function(format) {
193 return intTextureFormats.indexOf(format) < 0 &&
194 unsignedIntTextureFormats.indexOf(format) < 0 &&
195 depthTextureFormats.indexOf(format);
198 const expectedColorByInternalFormat = {};
199 expectedColorByInternalFormat[gl.SRGB8_ALPHA8] = [225, 188, 137, 255];
201 function clearFloat(gl) {
202 gl.clearBufferfv(gl.COLOR, 0, [0, 0, 0, 0]);
205 function clearInt(gl) {
206 gl.clearBufferiv(gl.COLOR, 0, [0, 0, 0, 0]);
209 function clearUint(gl) {
210 gl.clearBufferuiv(gl.COLOR, 0, [0, 0, 0, 0]);
214 function checkData(data, expected, internalFormat, tolerance) {
215 const internalFormatInfo = textureInternalFormatInfo[internalFormat];
216 const validChannels = validChannelsByTextureFormat[internalFormatInfo.textureFormat];
217 if (!validChannels) {
218 testFailed('oops');
219 return;
221 for (let y = 0; y < texHeight; ++y) {
222 for (let x = 0; x < texWidth; ++x) {
223 for (let c = 0; c < validChannels.length; ++c) {
224 if (validChannels[c]) {
225 const offset = (y * texWidth + x) * 4 + c;
226 const pixel = data[offset];
227 const diff = Math.abs(pixel - expected[c]);
228 if (diff > tolerance) {
229 testFailed(`pixel ${x},${y} channel ${c} was ${pixel} expected ${expected[c]} +/- ${tolerance}`);
230 return;
236 testPassed(`data was ${expected.join(',')}`);
239 function checkFloat(gl, textureInfo, expected) {
240 const data = new Uint8Array(texWidth * texHeight * 4);
241 gl.readPixels(0, 0, texWidth, texHeight, gl.RGBA, gl.UNSIGNED_BYTE, data);
242 const internalFormat = textureInfo.internalFormat;
243 wtu.glErrorShouldBe(gl, gl.NO_ERROR, `No errors from readPixels with ${wtu.glEnumToString(gl, internalFormat)}`);
244 checkData(data, expected, internalFormat, 9);
247 function checkInt(gl, textureInfo, expected) {
248 const data = new Int32Array(texWidth * texHeight * 4);
249 gl.readPixels(0, 0, texWidth, texHeight, gl.RGBA_INTEGER, gl.INT, data);
250 const internalFormat = textureInfo.internalFormat;
251 wtu.glErrorShouldBe(gl, gl.NO_ERROR, `No errors from readPixels with ${wtu.glEnumToString(gl, internalFormat)}`);
252 checkData(data, expected, internalFormat, 0);
255 function checkUint(gl, textureInfo, expected) {
256 const data = new Uint32Array(texWidth * texHeight * 4);
257 gl.readPixels(0, 0, texWidth, texHeight, gl.RGBA_INTEGER, gl.UNSIGNED_INT, data);
258 const internalFormat = textureInfo.internalFormat;
259 wtu.glErrorShouldBe(gl, gl.NO_ERROR, `No errors from readPixels with ${wtu.glEnumToString(gl, internalFormat)}`);
260 checkData(data, expected, internalFormat, 0);
263 const expectedFloatColor = [.75 * 255 | 0, .5 * 255 | 0, .25 * 255 | 0, 1 * 255 | 0];
264 const floatTypes = [
265 { outType: 'vec4', outValue: 'vec4(.75, .5, .25, 1)', expected: expectedFloatColor, clear: clearFloat, check: checkFloat, target: gl.TEXTURE_2D, },
266 { outType: 'vec4', outValue: 'vec4(.75, .5, .25, 1)', expected: expectedFloatColor, clear: clearFloat, check: checkFloat, target: gl.TEXTURE_3D, },
267 { outType: 'vec4', outValue: 'vec4(.75, .5, .25, 1)', expected: expectedFloatColor, clear: clearFloat, check: checkFloat, target: gl.TEXTURE_2D_ARRAY, },
270 const expectedIntColor = [1, 2, 4, 3];
271 const signedIntTypes = [
272 { outType: 'ivec4', outValue: 'ivec4(1, 2, 4, 3)', expected: expectedIntColor, clear: clearInt, check: checkInt, target: gl.TEXTURE_2D, },
273 { outType: 'ivec4', outValue: 'ivec4(1, 2, 4, 3)', expected: expectedIntColor, clear: clearInt, check: checkInt, target: gl.TEXTURE_3D, },
274 { outType: 'ivec4', outValue: 'ivec4(1, 2, 4, 3)', expected: expectedIntColor, clear: clearInt, check: checkInt, target: gl.TEXTURE_2D_ARRAY, },
277 const expectedUintColor = [1, 2, 4, 3];
278 const unsignedIntTypes = [
279 { outType: 'uvec4', outValue: 'uvec4(1, 2, 4, 3)', expected: expectedUintColor, clear: clearUint, check: checkUint, target: gl.TEXTURE_2D, },
280 { outType: 'uvec4', outValue: 'uvec4(1, 2, 4, 3)', expected: expectedUintColor, clear: clearUint, check: checkUint, target: gl.TEXTURE_3D, },
281 { outType: 'uvec4', outValue: 'uvec4(1, 2, 4, 3)', expected: expectedUintColor, clear: clearUint, check: checkUint, target: gl.TEXTURE_2D_ARRAY, },
285 * Gets the number of bytes per element for a given internalFormat / type
286 * @param {number} internalFormat The internalFormat parameter from texImage2D etc..
287 * @param {number} type The type parameter for texImage2D etc..
288 * @return {number} the number of bytes per element for the given internalFormat, type combo
289 * @memberOf module:twgl/textures
291 function getBytesPerElementForInternalFormat(internalFormat, type) {
292 const info = textureInternalFormatInfo[internalFormat];
293 if (!info) {
294 throw "unknown internal format";
296 const bytesPerElement = info.bytesPerElementMap[type];
297 if (bytesPerElement === undefined) {
298 throw "unknown internal format";
300 return bytesPerElement;
303 function make2DTexture(gl, target, internalFormat, format, type) {
304 gl.texImage2D(target, 0, internalFormat, texWidth, texHeight, 0, format, type, null);
307 function make3DTexture(gl, target, internalFormat, format, type) {
308 gl.texImage3D(target, 0, internalFormat, texWidth, texHeight, texDepth, 0, format, type, null);
311 function attach2DTexture(gl, target, texture) {
312 const level = 0;
313 gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, target, texture, level);
316 function attach3DTexture(gl, target, texture) {
317 const level = 0;
318 const slice = texDepth - 1;
319 gl.framebufferTextureLayer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, texture, level, slice);
322 const targets = {};
323 targets[gl.TEXTURE_2D] = { make: make2DTexture, attach: attach2DTexture, },
324 targets[gl.TEXTURE_3D] = { make: make3DTexture, attach: attach3DTexture, },
325 targets[gl.TEXTURE_2D_ARRAY] = { make: make3DTexture, attach: attach3DTexture, },
327 debug("create textures");
328 Object.keys(targets).forEach(function(target) {
329 debug("");
330 target = parseInt(target);
331 debug(wtu.glEnumToString(gl, target))
332 const targetInfo = targets[target];
333 targetInfo.textures = [];
334 Object.keys(textureInternalFormatInfo).forEach(function(internalFormat) {
335 internalFormat = parseInt(internalFormat);
336 const isDepthFormat = depthTextureFormats.indexOf(internalFormat) >= 0;
337 if (isDepthFormat) {
338 return;
340 const info = textureInternalFormatInfo[internalFormat];
341 if (!info.colorRenderable) {
342 return;
344 const texture = gl.createTexture();
345 gl.bindTexture(target, texture);
346 targetInfo.make(gl, target, internalFormat, info.textureFormat, info.type[0]);
347 targetInfo.textures.push({
348 internalFormat: internalFormat,
349 texture: texture,
351 gl.texParameteri(target, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
352 gl.texParameteri(target, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
353 wtu.glErrorShouldBe(gl, gl.NO_ERROR, `No errors from setup for ${wtu.glEnumToString(gl, target)} ${wtu.glEnumToString(gl, internalFormat)}`);
357 // set the canvas to a known color
358 const half = 127 / 255;
359 gl.clearColor(half, half, half, half);
360 gl.clear(gl.COLOR_BUFFER_BIT);
361 gl.clearColor(0, 0, 0, 0);
363 const framebuffer = gl.createFramebuffer();
364 gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer);
365 gl.viewport(0, 0, texWidth, texHeight);
367 const rb = gl.createRenderbuffer();
368 gl.bindRenderbuffer(gl.RENDERBUFFER, rb);
369 gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, texWidth, texHeight);
371 testTypes('float', floatTypes, floatTextureFormats);
372 testTypes('int', signedIntTypes, intTextureFormats);
373 testTypes('unsigned', unsignedIntTypes, unsignedIntTextureFormats);
375 gl.bindFramebuffer(gl.FRAMEBUFFER, null);
376 wtu.checkCanvas(gl, [127, 127, 127, 127], "canvas should be [127, 127, 127, 127]");
378 function testTypes(label, types, compatibleFormats) {
379 debug('');
380 types.forEach(function(typeInfo) {
381 debug(`\nchecking ${wtu.glEnumToString(gl, typeInfo.target)} with ${label} texture formats`);
382 const program = wtu.setupProgram(gl, ['vshader', makeFragmentShader(typeInfo)], [], console.log.bind(console));
383 if (!program) {
384 testFailed("Loading program failed");
385 return;
387 testPassed("Loading program succeeded");
389 const target = typeInfo.target;
390 const targetInfo = targets[target];
391 targetInfo.textures.filter(function(textureInfo) {
392 return compatibleFormats.indexOf(textureInfo.internalFormat) >= 0;
393 }).forEach(function(textureInfo) {
394 const internalFormat = textureInfo.internalFormat;
395 const desc = `${wtu.glEnumToString(gl, target)} ${wtu.glEnumToString(gl, internalFormat)}`;
396 const expected = expectedColorByInternalFormat[internalFormat] || typeInfo.expected;
398 debug('');
399 debug(desc);
401 targetInfo.attach(gl, target, textureInfo.texture);
402 wtu.framebufferStatusShouldBe(gl, gl.FRAMEBUFFER, gl.FRAMEBUFFER_COMPLETE, `for ${desc}`);
403 typeInfo.clear(gl);
404 if (wtu.glErrorShouldBe(gl, gl.NO_ERROR, `No errors from clear to ${desc}`)) {
405 return;
407 typeInfo.check(gl, textureInfo, [0, 0, 0, 0]);
408 gl.drawArrays(gl.POINTS, 0, 1);
409 if (wtu.glErrorShouldBe(gl, gl.NO_ERROR, `No errors from render to ${desc}`)) {
410 return;
412 typeInfo.check(gl, textureInfo, expected);
414 typeInfo.clear(gl);
415 if (wtu.glErrorShouldBe(gl, gl.NO_ERROR, `No errors from clear to ${desc}`)) {
416 return;
418 typeInfo.check(gl, textureInfo, [0, 0, 0, 0]);
420 gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, rb);
421 wtu.framebufferStatusShouldBe(gl, gl.FRAMEBUFFER, gl.FRAMEBUFFER_COMPLETE, `for ${desc} with depth renderbuffer`);
422 gl.clearBufferfv(gl.DEPTH, 0, [1]);
423 gl.drawArrays(gl.POINTS, 0, 1);
424 gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, null);
426 wtu.glErrorShouldBe(gl, gl.NO_ERROR, `No errors from render to ${desc}`);
428 typeInfo.check(gl, textureInfo, expected);
434 debug("");
435 var successfullyParsed = true;
436 </script>
437 <script src="../../js/js-test-post.js"></script>
439 </body>
440 </html>