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.
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/desktop-gl-constants.js"></script>
14 <script src=
"../../js/webgl-test-utils.js"></script>
17 <div id=
"description"></div>
18 <div id=
"console"></div>
22 description("Tests texture uploads with ArrayBufferView+offsets");
24 var wtu
= WebGLTestUtils
;
25 var gl
= wtu
.create3DContext(null, undefined, 2);
26 console
.log(gl
.getParameter(gl
.VERSION
));
30 function arrToStr(arr
) {
31 return "[" + arr
.map(x
=> x
.toString()).join(", ") + "]";
34 function shouldBeWas(shouldBe
, was
, info
) {
35 var text
= "Should be " + shouldBe
+ ", was " + was
+ ".";
37 text
= info
+ ": " + text
;
40 if (shouldBe
== was
) {
49 function shouldBeWasArr(shouldBe
, was
, info
) {
50 if (shouldBe
.length
!= was
.length
) {
51 testFailed("Length should be " + shouldBe
.length
+ ", was " + was
.length
+ ".");
55 return shouldBeWas(arrToStr(shouldBe
), arrToStr(was
), info
);
69 var fb
= gl
.createFramebuffer();
71 function probeWithBadOffset(fnTest
, info
) {
74 testFailed("Does not support " + info
+ " with offsets into views.");
80 // fn(view, offset, expectedError, expectedResult)
83 var readPixelView
= new Uint8Array(4);
84 var testView
= new Uint8Array(fibArr
);
86 function testTexOrSubImage(funcName
, fnTexOrSubImage
) {
90 var fnProbe = function(viewOffset
) {
91 fnTexOrSubImage(gl
.RGBA
, gl
.UNSIGNED_BYTE
, testView
, viewOffset
);
94 if (!probeWithBadOffset(fnProbe
, funcName
))
97 for (var i
= 0; i
<= testView
.length
+1; i
++) {
100 fnTexOrSubImage(gl
.RGBA
, gl
.UNSIGNED_BYTE
, testView
, i
);
102 var effectiveViewLen
= testView
.length
- i
;
104 if (effectiveViewLen
>= 4) {
105 wtu
.glErrorShouldBe(gl
, gl
.NO_ERROR
);
107 gl
.readPixels(0, 0, 1, 1, gl
.RGBA
, gl
.UNSIGNED_BYTE
, readPixelView
);
108 wtu
.glErrorShouldBe(gl
, gl
.NO_ERROR
);
109 shouldBeWasArr(testView
.slice(i
, i
+4), readPixelView
);
112 wtu
.glErrorShouldBe(gl
, gl
.INVALID_OPERATION
);
118 var yellow565
= (0x1f << 11) | (0x3f << 5);
119 var cyan565
= (0x3f << 5) | 0x1f;
120 var arr565
= [yellow565
, cyan565
];
121 var view565
= new Uint16Array(arr565
);
123 function rgb888to565(arr888
) {
124 return ((arr888
[0] >> 3) << 11) | ((arr888
[1] >> 2) << 5) | (arr888
[2] >> 3);
127 for (var i
= 0; i
<= arr565
.length
+1; i
++) {
128 debug("rgb565, offset=" + i
);
130 fnTexOrSubImage(gl
.RGB
, gl
.UNSIGNED_SHORT_5_6_5
, view565
, i
);
132 var effectiveViewLen
= arr565
.length
- i
;
134 if (effectiveViewLen
>= 1) {
135 wtu
.glErrorShouldBe(gl
, gl
.NO_ERROR
);
137 gl
.readPixels(0, 0, 1, 1, gl
.RGBA
, gl
.UNSIGNED_BYTE
, readPixelView
);
138 debug(arrToStr(readPixelView
));
139 wtu
.glErrorShouldBe(gl
, gl
.NO_ERROR
);
140 shouldBeWas(arr565
[i
], rgb888to565(readPixelView
));
143 wtu
.glErrorShouldBe(gl
, gl
.INVALID_OPERATION
);
148 var fn2D = function(format
, type
, view
, viewOffset
) {
149 gl
.texImage2D(gl
.TEXTURE_2D
, 0, format
, 1, 1, 0, format
, type
, view
, viewOffset
);
152 var fnSub2D = function(format
, type
, view
, viewOffset
) {
153 gl
.texImage2D(gl
.TEXTURE_2D
, 0, format
, 1, 1, 0, format
, type
, null);
154 gl
.texSubImage2D(gl
.TEXTURE_2D
, 0, 0, 0, 1, 1, format
, type
, view
, viewOffset
);
157 var fn3D = function(format
, type
, view
, viewOffset
) {
158 gl
.texImage3D(gl
.TEXTURE_3D
, 0, format
, 1, 1, 1, 0, format
, type
, view
, viewOffset
);
161 var fnSub3D = function(format
, type
, view
, viewOffset
) {
162 gl
.texImage3D(gl
.TEXTURE_3D
, 0, format
, 1, 1, 1, 0, format
, type
, null);
163 gl
.texSubImage3D(gl
.TEXTURE_3D
, 0, 0, 0, 0, 1, 1, 1, format
, type
, view
, viewOffset
);
168 var tex2d
= gl
.createTexture();
169 gl
.bindTexture(gl
.TEXTURE_2D
, tex2d
);
171 gl
.bindFramebuffer(gl
.FRAMEBUFFER
, fb
);
172 gl
.framebufferTexture2D(gl
.FRAMEBUFFER
, gl
.COLOR_ATTACHMENT0
, gl
.TEXTURE_2D
, tex2d
, 0);
174 testTexOrSubImage("texImage2D", fn2D
);
175 testTexOrSubImage("texSubImage2D", fnSub2D
);
179 var tex3d
= gl
.createTexture();
180 gl
.bindTexture(gl
.TEXTURE_3D
, tex3d
);
181 gl
.texImage3D(gl
.TEXTURE_3D
, 0, gl
.RGBA
, 1, 1, 1, 0, gl
.RGBA
, gl
.UNSIGNED_BYTE
, null);
183 gl
.bindFramebuffer(gl
.FRAMEBUFFER
, fb
);
184 gl
.framebufferTextureLayer(gl
.FRAMEBUFFER
, gl
.COLOR_ATTACHMENT0
, tex3d
, 0, 0);
186 testTexOrSubImage("texImage3D", fn3D
);
187 testTexOrSubImage("texSubImage3D", fnSub3D
);
192 var compressedFormat
= 0;
193 var compressedByteCount
;
195 if (gl
.getExtension("WEBGL_compressed_texture_s3tc")) {
196 var e
= gl
.getExtension("WEBGL_compressed_texture_s3tc");
197 compressedFormat
= e
.COMPRESSED_RGB_S3TC_DXT1_EXT
;
198 compressedByteCount
= 8;
199 } else if (gl
.getExtension("WEBGL_compressed_texture_etc")) {
200 var e
= gl
.getExtension("WEBGL_compressed_texture_etc");
201 compressedFormat
= e
.COMPRESSED_RGB8_ETC2
;
202 compressedByteCount
= 8;
204 debug("No compressed texture format found. Skipping compressedTex(Sub)Image tests.");
210 var view
= new Uint8Array(compressedByteCount
+1);
212 var fn2D = function(viewOffset
) {
213 gl
.compressedTexImage2D(gl
.TEXTURE_2D
, 0, compressedFormat
, 4, 4, 0,
214 view
, viewOffset
, compressedByteCount
);
217 var fnSub2D = function(viewOffset
) {
218 gl
.compressedTexImage2D(gl
.TEXTURE_2D
, 0, compressedFormat
, 4, 4, 0,
219 view
, 0, compressedByteCount
);
220 gl
.compressedTexSubImage2D(gl
.TEXTURE_2D
, 0, 0, 0, 4, 4, compressedFormat
,
221 view
, viewOffset
, compressedByteCount
);
224 var fn3D = function(viewOffset
) {
225 gl
.compressedTexImage3D(gl
.TEXTURE_2D_ARRAY
, 0, compressedFormat
, 4, 4, 1, 0,
226 view
, viewOffset
, compressedByteCount
);
229 var fnSub3D = function(viewOffset
) {
230 gl
.compressedTexImage3D(gl
.TEXTURE_2D_ARRAY
, 0, compressedFormat
, 4, 4, 1, 0,
231 view
, 0, compressedByteCount
);
232 gl
.compressedTexSubImage3D(gl
.TEXTURE_2D_ARRAY
, 0, 0, 0, 0, 4, 4, 1, compressedFormat
,
233 view
, viewOffset
, compressedByteCount
);
238 var testFunc = function(funcName
, fnToTest
) {
242 if (!probeWithBadOffset(fnToTest
, funcName
))
245 var viewLength
= view
.length
;
246 var subViewLength
= compressedByteCount
;
248 for (var i
= 0; i
<= viewLength
+1; i
++) {
249 debug("offset=" + i
);
252 var effectiveViewLen
= viewLength
- i
;
254 if (effectiveViewLen
>= subViewLength
) {
255 wtu
.glErrorShouldBe(gl
, gl
.NO_ERROR
);
258 wtu
.glErrorShouldBe(gl
, gl
.INVALID_VALUE
);
263 var tex2d
= gl
.createTexture();
264 gl
.bindTexture(gl
.TEXTURE_2D
, tex2d
);
265 testFunc("compressedTexImage2D" , fn2D
);
266 testFunc("compressedTexSubImage2D", fnSub2D
);
268 var tex3d
= gl
.createTexture();
269 gl
.bindTexture(gl
.TEXTURE_2D_ARRAY
, tex3d
);
270 testFunc("compressedTexImage3D" , fn3D
);
271 testFunc("compressedTexSubImage3D", fnSub3D
);
278 gl
.bindFramebuffer(gl
.FRAMEBUFFER
, null);
280 var testColor
= [10, 20, 30, 40];
281 gl
.clearColor(testColor
[0]/255.0,
285 gl
.clear(gl
.COLOR_BUFFER_BIT
);
286 var readPixelView
= new Uint8Array(6);
288 function doReadPixels(viewOffset
) {
289 gl
.readPixels(0, 0, 1, 1, gl
.RGBA
, gl
.UNSIGNED_BYTE
, readPixelView
, viewOffset
);
290 return readPixelView
;
293 if (!probeWithBadOffset(doReadPixels
, "doReadPixels"))
296 for (var i
= 0; i
<= readPixelView
.length
+1; i
++) {
297 debug("offset=" + i
);
298 var res
= doReadPixels(i
);
299 var effectiveViewLen
= readPixelView
.length
- i
;
301 if (effectiveViewLen
>= 4) {
302 wtu
.glErrorShouldBe(gl
, gl
.NO_ERROR
);
303 shouldBeWasArr(testColor
, res
.slice(i
,i
+4));
305 } else if (effectiveViewLen
>= 0) {
306 wtu
.glErrorShouldBe(gl
, gl
.INVALID_OPERATION
);
309 wtu
.glErrorShouldBe(gl
, gl
.INVALID_VALUE
);
315 var successfullyParsed
= true;
318 <script src=
"../../js/js-test-post.js"></script>