ext-float-blend.js (8721B)
1 'use strict'; 2 3 const trivialVsSrc = ` 4 void main() 5 { 6 gl_Position = vec4(0,0,0,1); 7 } 8 `; 9 const trivialFsSrc = ` 10 void main() 11 { 12 gl_FragColor = vec4(0,1,0,1); 13 } 14 `; 15 const trivialVsMrtSrc100 = ` 16 void main() 17 { 18 gl_Position = vec4(0,0,0,1); 19 } 20 `; 21 const trivialFsMrtSrc100 = ` 22 #extension GL_EXT_draw_buffers : require 23 precision mediump float; 24 void main() 25 { 26 gl_FragData[0] = vec4(1, 0, 0, 1); 27 gl_FragData[1] = vec4(0, 1, 0, 1); 28 } 29 `; 30 const trivialVsMrtSrc300 = `#version 300 es 31 void main() 32 { 33 gl_Position = vec4(0,0,0,1); 34 } 35 `; 36 const trivialFsMrtSrc300 = `#version 300 es 37 precision mediump float; 38 layout(location = 0) out vec4 o_color0; 39 layout(location = 1) out vec4 o_color1; 40 void main() 41 { 42 o_color0 = vec4(1, 0, 0, 1); 43 o_color1 = vec4(0, 1, 0, 1); 44 } 45 `; 46 47 function testExtFloatBlend(internalFormat) { 48 const shouldBlend = gl.getSupportedExtensions().indexOf('EXT_float_blend') != -1; 49 50 const prog = wtu.setupProgram(gl, [trivialVsSrc, trivialFsSrc]); 51 gl.useProgram(prog); 52 53 const tex = gl.createTexture(); 54 gl.bindTexture(gl.TEXTURE_2D, tex); 55 gl.texImage2D(gl.TEXTURE_2D, 0, internalFormat, 1, 1, 0, gl.RGBA, gl.FLOAT, null); 56 57 const fb = gl.createFramebuffer(); 58 gl.bindFramebuffer(gl.FRAMEBUFFER, fb); 59 gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex, 0); 60 shouldBe('gl.checkFramebufferStatus(gl.FRAMEBUFFER)', 'gl.FRAMEBUFFER_COMPLETE'); 61 62 gl.disable(gl.BLEND); 63 gl.drawArrays(gl.POINTS, 0, 1); 64 wtu.glErrorShouldBe(gl, 0, 'Float32 draw target without blending'); 65 66 gl.enable(gl.BLEND); 67 gl.drawArrays(gl.POINTS, 0, 1); 68 wtu.glErrorShouldBe(gl, shouldBlend ? 0 : gl.INVALID_OPERATION, 69 'Float32 blending is ' + (shouldBlend ? '' : 'not ') + 'allowed '); 70 71 gl.deleteFramebuffer(fb); 72 gl.deleteTexture(tex); 73 } 74 75 function testExtFloatBlendMRTImpl(version, internalFormat, shaders, attachments, drawBuffers) { 76 const shouldBlend = gl.getSupportedExtensions().indexOf('EXT_float_blend') != -1; 77 78 const prog = wtu.setupProgram(gl, shaders); 79 gl.useProgram(prog); 80 81 const tex1 = gl.createTexture(); 82 gl.bindTexture(gl.TEXTURE_2D, tex1); 83 gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, null); 84 85 const tex2 = gl.createTexture(); 86 gl.bindTexture(gl.TEXTURE_2D, tex2); 87 gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, null); 88 89 const texF1 = gl.createTexture(); 90 gl.bindTexture(gl.TEXTURE_2D, texF1); 91 gl.texImage2D(gl.TEXTURE_2D, 0, internalFormat, 1, 1, 0, gl.RGBA, gl.FLOAT, null); 92 93 const texF2 = gl.createTexture(); 94 gl.bindTexture(gl.TEXTURE_2D, texF2); 95 gl.texImage2D(gl.TEXTURE_2D, 0, internalFormat, 1, 1, 0, gl.RGBA, gl.FLOAT, null); 96 97 const fb = gl.createFramebuffer(); 98 gl.bindFramebuffer(gl.FRAMEBUFFER, fb); 99 gl.framebufferTexture2D(gl.FRAMEBUFFER, attachments[0], gl.TEXTURE_2D, tex1, 0); 100 gl.framebufferTexture2D(gl.FRAMEBUFFER, attachments[1], gl.TEXTURE_2D, tex2, 0); 101 shouldBe('gl.checkFramebufferStatus(gl.FRAMEBUFFER)', 'gl.FRAMEBUFFER_COMPLETE'); 102 103 drawBuffers(attachments); 104 105 gl.enable(gl.BLEND); 106 107 gl.drawArrays(gl.POINTS, 0, 1); 108 wtu.glErrorShouldBe(gl, 0, 'No Float32 color attachment'); 109 110 if (version < 2) { 111 // EXT_draw_buffers require all color buffers having the same number of bitplanes 112 gl.framebufferTexture2D(gl.FRAMEBUFFER, attachments[0], gl.TEXTURE_2D, texF1, 0); 113 gl.framebufferTexture2D(gl.FRAMEBUFFER, attachments[1], gl.TEXTURE_2D, texF2, 0); 114 shouldBe('gl.checkFramebufferStatus(gl.FRAMEBUFFER)', 'gl.FRAMEBUFFER_COMPLETE'); 115 gl.drawArrays(gl.POINTS, 0, 1); 116 wtu.glErrorShouldBe(gl, shouldBlend ? 0 : gl.INVALID_OPERATION, 117 'Float32 blending is ' + (shouldBlend ? '' : 'not ') + 'allowed '); 118 } else { 119 gl.framebufferTexture2D(gl.FRAMEBUFFER, attachments[0], gl.TEXTURE_2D, texF1, 0); 120 shouldBe('gl.checkFramebufferStatus(gl.FRAMEBUFFER)', 'gl.FRAMEBUFFER_COMPLETE'); 121 gl.drawArrays(gl.POINTS, 0, 1); 122 wtu.glErrorShouldBe(gl, shouldBlend ? 0 : gl.INVALID_OPERATION, 123 'Float32 blending is ' + (shouldBlend ? '' : 'not ') + 'allowed '); 124 125 gl.framebufferTexture2D(gl.FRAMEBUFFER, attachments[1], gl.TEXTURE_2D, texF2, 0); 126 shouldBe('gl.checkFramebufferStatus(gl.FRAMEBUFFER)', 'gl.FRAMEBUFFER_COMPLETE'); 127 gl.drawArrays(gl.POINTS, 0, 1); 128 wtu.glErrorShouldBe(gl, shouldBlend ? 0 : gl.INVALID_OPERATION, 129 'Float32 blending is ' + (shouldBlend ? '' : 'not ') + 'allowed '); 130 131 gl.framebufferTexture2D(gl.FRAMEBUFFER, attachments[0], gl.TEXTURE_2D, tex1, 0); 132 shouldBe('gl.checkFramebufferStatus(gl.FRAMEBUFFER)', 'gl.FRAMEBUFFER_COMPLETE'); 133 gl.drawArrays(gl.POINTS, 0, 1); 134 wtu.glErrorShouldBe(gl, shouldBlend ? 0 : gl.INVALID_OPERATION, 135 'Float32 blending is ' + (shouldBlend ? '' : 'not ') + 'allowed '); 136 137 drawBuffers([attachments[0]]); 138 shouldBe('gl.checkFramebufferStatus(gl.FRAMEBUFFER)', 'gl.FRAMEBUFFER_COMPLETE'); 139 140 gl.drawArrays(gl.POINTS, 0, 1); 141 wtu.glErrorShouldBe(gl, 0, 'Float32 color attachment draw buffer is not enabled'); 142 143 drawBuffers(attachments); 144 gl.framebufferTexture2D(gl.FRAMEBUFFER, attachments[1], gl.TEXTURE_2D, tex2, 0); 145 shouldBe('gl.checkFramebufferStatus(gl.FRAMEBUFFER)', 'gl.FRAMEBUFFER_COMPLETE'); 146 147 gl.drawArrays(gl.POINTS, 0, 1); 148 wtu.glErrorShouldBe(gl, 0, 'No Float32 color attachment'); 149 } 150 151 gl.deleteFramebuffer(fb); 152 gl.deleteTexture(tex1); 153 gl.deleteTexture(tex2); 154 gl.deleteTexture(texF1); 155 gl.deleteTexture(texF2); 156 } 157 158 function testExtFloatBlendMRT(version, drawBuffersExt) { 159 if (version < 2) { 160 if (!drawBuffersExt) return; 161 testExtFloatBlendMRTImpl( 162 version, 163 gl.RGBA, 164 [trivialVsMrtSrc100, trivialFsMrtSrc100], 165 [drawBuffersExt.COLOR_ATTACHMENT0_WEBGL, drawBuffersExt.COLOR_ATTACHMENT1_WEBGL], 166 drawBuffersExt.drawBuffersWEBGL.bind(drawBuffersExt) 167 ); 168 } else { 169 testExtFloatBlendMRTImpl( 170 version, 171 gl.RGBA32F, 172 [trivialVsMrtSrc300, trivialFsMrtSrc300], 173 [gl.COLOR_ATTACHMENT0, gl.COLOR_ATTACHMENT1], 174 gl.drawBuffers.bind(gl) 175 ); 176 } 177 } 178 179 function testExtFloatBlendNonFloat32TypeImpl(internalFormat, formats) { 180 const shouldBlend = gl.getSupportedExtensions().indexOf('EXT_float_blend') != -1; 181 182 const prog = wtu.setupProgram(gl, [trivialVsSrc, trivialFsSrc]); 183 gl.useProgram(prog); 184 185 gl.enable(gl.BLEND); 186 187 const tex = gl.createTexture(); 188 gl.bindTexture(gl.TEXTURE_2D, tex); 189 gl.texImage2D(gl.TEXTURE_2D, 0, internalFormat, 1, 1, 0, gl.RGBA, gl.FLOAT, null); 190 191 const fb = gl.createFramebuffer(); 192 gl.bindFramebuffer(gl.FRAMEBUFFER, fb); 193 gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex, 0); 194 shouldBe('gl.checkFramebufferStatus(gl.FRAMEBUFFER)', 'gl.FRAMEBUFFER_COMPLETE'); 195 196 gl.drawArrays(gl.POINTS, 0, 1); 197 wtu.glErrorShouldBe(gl, shouldBlend ? 0 : gl.INVALID_OPERATION, 198 'Float32 blending is ' + (shouldBlend ? '' : 'not ') + 'allowed '); 199 200 gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, null); 201 gl.drawArrays(gl.POINTS, 0, 1); 202 wtu.glErrorShouldBe(gl, 0, 'UNSIGNED_BYTE should blend anyway'); 203 204 for (let i = 0, len = formats.length; i < len; i++) { 205 gl.texImage2D(gl.TEXTURE_2D, 0, formats[i][0], 1, 1, 0, formats[i][1], formats[i][2], null); 206 gl.drawArrays(gl.POINTS, 0, 1); 207 wtu.glErrorShouldBe(gl, 0, 'Any other float type which is not 32-bit-Float should blend anyway'); 208 } 209 210 gl.deleteFramebuffer(fb); 211 gl.deleteTexture(tex); 212 } 213 214 function testExtFloatBlendNonFloat32Type(version, oesTextureHalfFloat) { 215 if (version < 2) { 216 if (!oesTextureHalfFloat) return; 217 const formats = [ 218 [gl.RGBA, gl.RGBA, oesTextureHalfFloat.HALF_FLOAT_OES] 219 ]; 220 testExtFloatBlendNonFloat32TypeImpl(gl.RGBA, formats); 221 } else { 222 const formats = [ 223 [gl.RGBA16F, gl.RGBA, gl.HALF_FLOAT], 224 [gl.RGBA16F, gl.RGBA, gl.FLOAT], 225 [gl.RG16F, gl.RG, gl.FLOAT], 226 [gl.R16F, gl.RED, gl.FLOAT], 227 [gl.R11F_G11F_B10F, gl.RGB, gl.FLOAT] 228 ]; 229 testExtFloatBlendNonFloat32TypeImpl(gl.RGBA32F, formats); 230 } 231 } 232 233 /* 234 Copyright (c) 2019 The Khronos Group Inc. 235 Use of this source code is governed by an MIT-style license that can be 236 found in the LICENSE.txt file. 237 */