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 <title>WebGL BlitFramebuffer Tests
</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>
17 <canvas id=
"canvas" width=
"8" height=
"8"></canvas>
18 <div id=
"description"></div>
19 <div id=
"console"></div>
24 var wtu
= WebGLTestUtils
;
25 description("This test verifies the functionality of blitFramebuffer with multiple draw buffers (srgb image and linear image).");
27 var gl
= wtu
.create3DContext("canvas", undefined, 2);
32 testFailed("WebGL context does not exist");
34 testPassed("WebGL context exists");
36 var filters
= [gl
.LINEAR
, gl
.NEAREST
];
37 var drawbuffersFormats
= [linearMask
, srgbMask
, linearMask
| srgbMask
];
38 for (var ii
= 0; ii
< filters
.length
; ++ii
) {
39 for (var jj
= 0; jj
< drawbuffersFormats
.length
; ++jj
) {
40 blitframebuffer_srgb_and_linear_drawbuffers(gl
.SRGB8_ALPHA8
, drawbuffersFormats
[jj
], filters
[ii
]);
41 blitframebuffer_srgb_and_linear_drawbuffers(gl
.RGBA8
, drawbuffersFormats
[jj
], filters
[ii
]);
46 function blitframebuffer_srgb_and_linear_drawbuffers(readbufferFormat
, drawbuffersFormatMask
, filter
) {
48 debug("The filter is: " + wtu
.glEnumToString(gl
, filter
));
49 debug("Read buffer format is: " + wtu
.glEnumToString(gl
, readbufferFormat
));
50 var drawbuffersFormat
= "\0";
51 if (drawbuffersFormatMask
& linearMask
) {
52 drawbuffersFormat
+= " linear ";
54 if (drawbuffersFormatMask
& srgbMask
) {
55 drawbuffersFormat
+= " srgb ";
57 debug("The test have multiple draw buffers, the images are: " + drawbuffersFormat
);
59 var tex_srgb0
= gl
.createTexture();
60 var tex_srgb1
= gl
.createTexture();
61 var tex_linear0
= gl
.createTexture();
62 var tex_linear1
= gl
.createTexture();
63 var tex_read
= gl
.createTexture();
64 var fbo_read
= gl
.createFramebuffer();
65 var fbo_draw
= gl
.createFramebuffer();
67 // Create read buffer and feed data to the read buffer
69 var data
= new Uint8Array(size
* size
* 4);
70 var color
= [250, 100, 15, 255];
71 for (var ii
= 0; ii
< size
* size
* 4; ii
+= 4) {
72 for (var jj
= 0; jj
< 4; ++jj
) {
73 data
[ii
+ jj
] = color
[jj
];
76 gl
.bindTexture(gl
.TEXTURE_2D
, tex_read
);
77 gl
.texImage2D(gl
.TEXTURE_2D
, 0, readbufferFormat
, size
, size
, 0, gl
.RGBA
, gl
.UNSIGNED_BYTE
, data
);
78 gl
.bindFramebuffer(gl
.READ_FRAMEBUFFER
, fbo_read
);
79 gl
.framebufferTexture2D(gl
.READ_FRAMEBUFFER
, gl
.COLOR_ATTACHMENT0
, gl
.TEXTURE_2D
, tex_read
, 0);
80 wtu
.glErrorShouldBe(gl
, gl
.NO_ERROR
, "setup read framebuffer should succeed");
82 // Create multiple textures. Attach them as fbo's draw buffers.
83 gl
.bindFramebuffer(gl
.DRAW_FRAMEBUFFER
, fbo_draw
);
85 var drawbuffers
= [gl
.NONE
, gl
.NONE
, gl
.NONE
, gl
.NONE
];
86 if (drawbuffersFormatMask
& srgbMask
) {
87 gl
.bindTexture(gl
.TEXTURE_2D
, tex_srgb0
);
88 gl
.texImage2D(gl
.TEXTURE_2D
, 0, gl
.SRGB8_ALPHA8
, size
, size
, 0, gl
.RGBA
, gl
.UNSIGNED_BYTE
, null);
89 gl
.framebufferTexture2D(gl
.DRAW_FRAMEBUFFER
, gl
.COLOR_ATTACHMENT0
, gl
.TEXTURE_2D
, tex_srgb0
, 0);
90 gl
.bindTexture(gl
.TEXTURE_2D
, tex_srgb1
);
91 gl
.texImage2D(gl
.TEXTURE_2D
, 0, gl
.SRGB8_ALPHA8
, size
, size
, 0, gl
.RGBA
, gl
.UNSIGNED_BYTE
, null);
92 gl
.framebufferTexture2D(gl
.DRAW_FRAMEBUFFER
, gl
.COLOR_ATTACHMENT2
, gl
.TEXTURE_2D
, tex_srgb1
, 0);
93 drawbuffers
[0] = gl
.COLOR_ATTACHMENT0
;
94 drawbuffers
[2] = gl
.COLOR_ATTACHMENT2
;
97 if (drawbuffersFormatMask
& linearMask
) {
98 gl
.bindTexture(gl
.TEXTURE_2D
, tex_linear0
);
99 gl
.texImage2D(gl
.TEXTURE_2D
, 0, gl
.RGBA8
, size
, size
, 0, gl
.RGBA
, gl
.UNSIGNED_BYTE
, null);
100 gl
.framebufferTexture2D(gl
.DRAW_FRAMEBUFFER
, gl
.COLOR_ATTACHMENT1
, gl
.TEXTURE_2D
, tex_linear0
, 0);
101 gl
.bindTexture(gl
.TEXTURE_2D
, tex_linear1
);
102 gl
.texImage2D(gl
.TEXTURE_2D
, 0, gl
.RGBA8
, size
, size
, 0, gl
.RGBA
, gl
.UNSIGNED_BYTE
, null);
103 gl
.framebufferTexture2D(gl
.DRAW_FRAMEBUFFER
, gl
.COLOR_ATTACHMENT3
, gl
.TEXTURE_2D
, tex_linear1
, 0);
104 drawbuffers
[1] = gl
.COLOR_ATTACHMENT1
;
105 drawbuffers
[3] = gl
.COLOR_ATTACHMENT3
;
108 gl
.drawBuffers(drawbuffers
);
109 wtu
.glErrorShouldBe(gl
, gl
.NO_ERROR
, "setup draw framebuffer should succeed");
111 if (gl
.checkFramebufferStatus(gl
.DRAW_FRAMEBUFFER
) != gl
.FRAMEBUFFER_COMPLETE
||
112 gl
.checkFramebufferStatus(gl
.READ_FRAMEBUFFER
) != gl
.FRAMEBUFFER_COMPLETE
) {
113 testFailed("Framebuffer incomplete when setup draw framebuffer.");
117 // Blit to multiple draw buffers with srgb images and linear images
118 var dstSize
= size
- 1;
119 gl
.blitFramebuffer(0, 0, size
, size
, 0, 0, dstSize
, dstSize
, gl
.COLOR_BUFFER_BIT
, filter
);
120 wtu
.glErrorShouldBe(gl
, gl
.NO_ERROR
, "blitframebuffer should succeed");
122 // Read pixels from srgb images and linear images
123 var srgbPixels0
= new Uint8Array(dstSize
* dstSize
* 4);
124 var srgbPixels1
= new Uint8Array(dstSize
* dstSize
* 4);
125 var linearPixels0
= new Uint8Array(dstSize
* dstSize
* 4);
126 var linearPixels1
= new Uint8Array(dstSize
* dstSize
* 4);
127 gl
.bindFramebuffer(gl
.READ_FRAMEBUFFER
, fbo_draw
);
128 if (drawbuffersFormatMask
& srgbMask
) {
129 gl
.readBuffer(gl
.COLOR_ATTACHMENT0
);
130 gl
.readPixels(0, 0, dstSize
, dstSize
, gl
.RGBA
, gl
.UNSIGNED_BYTE
, srgbPixels0
);
131 gl
.readBuffer(gl
.COLOR_ATTACHMENT2
);
132 gl
.readPixels(0, 0, dstSize
, dstSize
, gl
.RGBA
, gl
.UNSIGNED_BYTE
, srgbPixels1
);
135 if (drawbuffersFormatMask
& linearMask
) {
136 gl
.readBuffer(gl
.COLOR_ATTACHMENT1
);
137 gl
.readPixels(0, 0, dstSize
, dstSize
, gl
.RGBA
, gl
.UNSIGNED_BYTE
, linearPixels0
);
138 gl
.readBuffer(gl
.COLOR_ATTACHMENT3
);
139 gl
.readPixels(0, 0, dstSize
, dstSize
, gl
.RGBA
, gl
.UNSIGNED_BYTE
, linearPixels1
);
141 wtu
.glErrorShouldBe(gl
, gl
.NO_ERROR
, "readpixels should succeed");
144 var expectedSRGBColor
= (readbufferFormat
== gl
.SRGB8_ALPHA8
) ? color
: wtu
.linearToSRGB(color
);
145 var expectedLinearColor
= (readbufferFormat
== gl
.SRGB8_ALPHA8
) ? wtu
.sRGBToLinear(color
) : color
;
147 for (var ii
= 0; ii
< dstSize
; ++ii
) {
148 for (var jj
= 0; jj
< dstSize
; ++jj
) {
149 var index
= (ii
* dstSize
+ jj
) * 4;
150 if (drawbuffersFormatMask
& srgbMask
) {
151 var srgbColor0
= [srgbPixels0
[index
], srgbPixels0
[index
+ 1], srgbPixels0
[index
+ 2], srgbPixels0
[index
+ 3]];
152 if (checkPixel(srgbColor0
, expectedSRGBColor
) == false) {
154 debug("Pixels comparison failed for the 1st sRGB image. Pixel at [" + jj
+ ", " + ii
+ "] should be (" + expectedSRGBColor
+ "), but the actual color is (" + srgbColor0
+ ")");
156 var srgbColor1
= [srgbPixels1
[index
], srgbPixels1
[index
+ 1], srgbPixels1
[index
+ 2], srgbPixels1
[index
+ 3]];
157 if (checkPixel(srgbColor1
, expectedSRGBColor
) == false) {
159 debug("Pixels comparison failed for the 2nd sRGB image. Pixel at [" + jj
+ ", " + ii
+ "] should be (" + expectedSRGBColor
+ "), but the actual color is (" + srgbColor1
+ ")");
163 if (drawbuffersFormatMask
& linearMask
) {
164 var linearColor0
= [linearPixels0
[index
], linearPixels0
[index
+ 1], linearPixels0
[index
+ 2], linearPixels0
[index
+ 3]];
165 if (checkPixel(linearColor0
, expectedLinearColor
) == false) {
167 debug("Pixel comparison failed for the 1st linear image. Pixel at [" + jj
+ ", " + ii
+ "] should be (" + color
+ "), but the actual color is (" + linearColor0
+ ")");
169 var linearColor1
= [linearPixels1
[index
], linearPixels1
[index
+ 1], linearPixels1
[index
+ 2], linearPixels1
[index
+ 3]];
170 if (checkPixel(linearColor1
, expectedLinearColor
) == false) {
172 debug("Pixel comparison failed for the 2nd linear image. Pixel at [" + jj
+ ", " + ii
+ "] should be (" + color
+ "), but the actual color is (" + linearColor1
+ ")");
177 if (failed
== false) {
178 testPassed("All pixels comparision passed!");
182 gl
.bindTexture(gl
.TEXTURE_2D
, null);
183 gl
.bindFramebuffer(gl
.READ_FRAMEBUFFER
, null);
184 gl
.bindFramebuffer(gl
.DRAW_FRAMEBUFFER
, null);
185 gl
.deleteTexture(tex_srgb0
);
186 gl
.deleteTexture(tex_linear0
);
187 gl
.deleteTexture(tex_srgb1
);
188 gl
.deleteTexture(tex_linear1
);
189 gl
.deleteTexture(tex_read
);
190 gl
.deleteFramebuffer(fbo_read
);
191 gl
.deleteFramebuffer(fbo_draw
);
194 function checkPixel(color
, expectedColor
) {
196 return (Math
.abs(color
[0] - expectedColor
[0]) <= tolerance
&&
197 Math
.abs(color
[1] - expectedColor
[1]) <= tolerance
&&
198 Math
.abs(color
[2] - expectedColor
[2]) <= tolerance
&&
199 Math
.abs(color
[3] - expectedColor
[3]) <= tolerance
);
202 var successfullyParsed
= true;
204 <script src=
"../../js/js-test-post.js"></script>