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/webgl-test-utils.js"></script>
14 <script src=
"../../../js/tests/tex-image-and-sub-image-utils.js"></script>
17 <canvas id=
"example" width=
"2" height=
"2"></canvas>
18 <div id=
"description"></div>
19 <div id=
"console"></div>
22 description('Verifies tex{Sub}Image{2|3}D code paths taking partial ArrayBufferView');
24 var wtu
= WebGLTestUtils
;
25 var tiu
= TexImageUtils
;
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;
34 buf
[ii
+ offset
] = ii
;
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.
44 var src
= ref
[ii
+ refOffset
];
45 if (ref
instanceof Float32Array
)
47 if (Math
.abs(src
- data
[ii
]) > tol
) {
48 testFailed("Element " + ii
+ ": expected " + src
+ ", got " + data
[ii
]);
52 return testPassed("texture data uploaded correctly");
55 function run2DTest(gl
, test
, width
, height
, srcOffset
, tol
) {
57 debug("Tesing tex{Sub}Image2D with sub source: internalformat = " + test
.internalformat
+
58 ", format = " + test
.format
+ ", type = " + test
.type
);
60 var program
= tiu
.setupTexturedQuad(gl
, test
.internalformat
);
62 testFailed("Failed to set up program");
66 var buf
= createSource(width
, height
, 1, test
.viewType
, srcOffset
);
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");
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");
87 comparePixels(buf
, srcOffset
, readBuf
, tol
);
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
],
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
],
96 wtu
.glErrorShouldBe(gl
, gl
.NO_ERROR
, "texSubImage2D succeeds with correct buffer and srcOffset");
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
);
104 gl
.deleteTexture(texture
);
105 gl
.deleteProgram(program
);
108 function run3DTest(gl
, test
, width
, height
, srcOffset
, tol
) {
110 debug("Tesing tex{Sub}Image3D with sub source: internalformat = " + test
.internalformat
+
111 ", format = " + test
.format
+ ", type = " + test
.type
);
113 var program
= tiu
.setupTexturedQuadWith3D(gl
, test
.internalformat
);
115 testFailed("Failed to set up program");
120 var buf
= createSource(width
, height
, depth
, test
.viewType
, srcOffset
);
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");
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");
142 comparePixels(buf
, srcOffset
, readBuf
, tol
);
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
],
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
],
151 wtu
.glErrorShouldBe(gl
, gl
.NO_ERROR
, "texSubImage3D succeeds with correct buffer and srcOffset");
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
);
159 gl
.deleteTexture(texture
);
160 gl
.deleteProgram(program
);
163 var gl
= wtu
.create3DContext("example", undefined, 2);
165 testFailed("Fail to get a WebGL context");
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', },
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
);
193 var successfullyParsed
= true;
195 <script src=
"../../../js/js-test-post.js"></script>