|
2163 | 2163 | } |
2164 | 2164 |
|
2165 | 2165 | function uploadSubData(target) { |
2166 | | - function checkResult(target, expectations, dim) { |
2167 | | - switch (target) { |
2168 | | - case gl.TEXTURE_2D: |
2169 | | - wtu.glErrorShouldBe(gl, expectations[0], "uploading compressed 2D texture data via compressedTexSubImage" + dim); |
2170 | | - break; |
2171 | | - case gl.TEXTURE_2D_ARRAY: |
2172 | | - wtu.glErrorShouldBe(gl, expectations[1], "uploading compressed 2D array texture data via compressedTexSubImage" + dim); |
2173 | | - break; |
2174 | | - case gl.TEXTURE_3D: |
2175 | | - wtu.glErrorShouldBe(gl, expectations[2], "uploading compressed 3D texture data via compressedTexSubImage" + dim); |
2176 | | - break; |
2177 | | - } |
2178 | | - } |
2179 | | - |
2180 | 2166 | gl.compressedTexSubImage2D(target, 0, 0, 0, width, height, format, data); |
2181 | 2167 | checkResult(target, [gl.NO_ERROR, gl.INVALID_ENUM, gl.INVALID_ENUM ], "2D"); |
2182 | 2168 |
|
|
2186 | 2172 | } |
2187 | 2173 | } |
2188 | 2174 |
|
| 2175 | + function uploadSubDataOffset(target) { |
| 2176 | + const blockSize = getBlockDimensions(format); |
| 2177 | + if ((width % blockSize.width) || (height % blockSize.height)) { |
| 2178 | + // Skip test for unaligned blocks |
| 2179 | + return; |
| 2180 | + } |
| 2181 | + |
| 2182 | + const x = blockSize.width; |
| 2183 | + const y = blockSize.height; |
| 2184 | + const blitWidth = width - x; |
| 2185 | + const blitHeight = height - y; |
| 2186 | + |
| 2187 | + // Offset the update by one horizontal and one vertical rows. |
| 2188 | + // ASTC block size is always 16 bytes (128 bits) |
| 2189 | + const offset = (width / blockSize.width + height / blockSize.height - 1) * 16; |
| 2190 | + |
| 2191 | + gl.compressedTexSubImage2D(target, 0, x, y, blitWidth, blitHeight, format, data, offset); |
| 2192 | + checkResult(target, [gl.NO_ERROR, gl.INVALID_ENUM, gl.INVALID_ENUM ], "2D", true); |
| 2193 | + |
| 2194 | + const srcLengthOverride = data.length - offset; |
| 2195 | + gl.compressedTexSubImage2D(target, 0, x, y, blitWidth, blitHeight, format, data, 0, srcLengthOverride); |
| 2196 | + checkResult(target, [gl.NO_ERROR, gl.INVALID_ENUM, gl.INVALID_ENUM ], "2D", true); |
| 2197 | + |
| 2198 | + if (useES3) { |
| 2199 | + gl.compressedTexSubImage3D(target, 0, x, y, 0, blitWidth, blitHeight, 1, format, data, offset); |
| 2200 | + checkResult(target, [gl.INVALID_ENUM, gl.NO_ERROR, gl.NO_ERROR], "3D", true); |
| 2201 | + |
| 2202 | + gl.compressedTexSubImage3D(target, 0, x, y, 0, blitWidth, blitHeight, 1, format, data, 0, srcLengthOverride); |
| 2203 | + checkResult(target, [gl.INVALID_ENUM, gl.NO_ERROR, gl.NO_ERROR], "3D", true); |
| 2204 | + } |
| 2205 | + } |
| 2206 | + |
2189 | 2207 | function setupFilledTexture(target) { |
2190 | 2208 | var tex = gl.createTexture(); |
2191 | 2209 | gl.bindTexture(target, tex); |
|
2277 | 2295 | checkSampling(gl.TEXTURE_2D) |
2278 | 2296 | gl.deleteTexture(tex); |
2279 | 2297 |
|
| 2298 | + // Upload with offsets |
| 2299 | + tex = setupEmptyTexture(gl.TEXTURE_2D, false); |
| 2300 | + wtu.glErrorShouldBe(gl, gl.NO_ERROR, "allocating empty compressed texture via compressedTexImage2D"); |
| 2301 | + uploadSubDataOffset(gl.TEXTURE_2D); |
| 2302 | + gl.deleteTexture(tex); |
| 2303 | + |
2280 | 2304 | // mutable filled |
2281 | 2305 | tex = setupFilledTexture(gl.TEXTURE_2D); |
2282 | 2306 | wtu.glErrorShouldBe(gl, gl.NO_ERROR, "allocating filled compressed texture via compressedTexImage2D"); |
|
2304 | 2328 | checkSampling(gl.TEXTURE_2D_ARRAY) |
2305 | 2329 | gl.deleteTexture(tex); |
2306 | 2330 |
|
| 2331 | + // Upload with offsets |
| 2332 | + tex = setupEmptyTexture(gl.TEXTURE_2D_ARRAY, false); |
| 2333 | + wtu.glErrorShouldBe(gl, gl.NO_ERROR, "allocating empty compressed texture array via compressedTexImage3D"); |
| 2334 | + uploadSubDataOffset(gl.TEXTURE_2D_ARRAY); |
| 2335 | + gl.deleteTexture(tex); |
| 2336 | + |
2307 | 2337 | // mutable filled |
2308 | 2338 | tex = setupFilledTexture(gl.TEXTURE_2D_ARRAY); |
2309 | 2339 | wtu.glErrorShouldBe(gl, gl.NO_ERROR, "allocating filled compressed texture array via compressedTexImage3D"); |
|
2338 | 2368 | } |
2339 | 2369 | gl.deleteTexture(tex); |
2340 | 2370 |
|
| 2371 | + // Upload with offsets |
| 2372 | + tex = setupEmptyTexture(gl.TEXTURE_3D, false); |
| 2373 | + if (hasHdr) { |
| 2374 | + wtu.glErrorShouldBe(gl, gl.NO_ERROR, "allocating empty compressed sliced 3D texture via compressedTexImage3D"); |
| 2375 | + checkErrorColor(); |
| 2376 | + uploadSubDataOffset(gl.TEXTURE_3D); |
| 2377 | + } else { |
| 2378 | + wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "allocating empty compressed sliced 3D texture via compressedTexImage3D"); |
| 2379 | + } |
| 2380 | + gl.deleteTexture(tex); |
| 2381 | + |
2341 | 2382 | // mutable filled |
2342 | 2383 | tex = setupFilledTexture(gl.TEXTURE_3D); |
2343 | 2384 | if (hasHdr) { |
|
2420 | 2461 | } |
2421 | 2462 | } |
2422 | 2463 |
|
| 2464 | +function checkResult(target, expectations, dim, offsets = false) { |
| 2465 | + const offsetStr = offsets ? " with x/y offsets" : ""; |
| 2466 | + switch (target) { |
| 2467 | + case gl.TEXTURE_2D: |
| 2468 | + wtu.glErrorShouldBe(gl, expectations[0], "uploading compressed 2D texture data via compressedTexSubImage" + dim + offsetStr); |
| 2469 | + break; |
| 2470 | + case gl.TEXTURE_2D_ARRAY: |
| 2471 | + wtu.glErrorShouldBe(gl, expectations[1], "uploading compressed 2D array texture data via compressedTexSubImage" + dim + offsetStr); |
| 2472 | + break; |
| 2473 | + case gl.TEXTURE_3D: |
| 2474 | + wtu.glErrorShouldBe(gl, expectations[2], "uploading compressed 3D texture data via compressedTexSubImage" + dim + offsetStr); |
| 2475 | + break; |
| 2476 | + } |
| 2477 | +} |
| 2478 | + |
2423 | 2479 | // Builds several tests from two arrays |
2424 | 2480 | // data gives each Uint8Array encoded data to use |
2425 | 2481 | // formats the associate format to decode the data |
|
2484 | 2540 | return { |
2485 | 2541 | width: parseInt(match[1], 10), |
2486 | 2542 | height: parseInt(match[2], 10) |
2487 | | - }; |
| 2543 | + }; |
2488 | 2544 | } |
2489 | 2545 | } |
2490 | 2546 | testFailed('Could not find block dimensions for format ' + ctu.formatToString(ext, format)); |
|
0 commit comments