same-buffer-two-binding-points.html (7274B)
1 <!-- 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. 5 --> 6 7 <!DOCTYPE html> 8 <html> 9 <head> 10 <meta charset="utf-8"> 11 <title>WebGL Transform Feedback Conformance Tests - one buffer bound to two binding points</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> 15 </head> 16 <body> 17 <div id="description"></div> 18 <div id="console"></div> 19 <script id="vshader" type="x-shader/x-vertex">#version 300 es 20 21 in vec4 in_data; 22 out vec4 out_add; 23 out vec4 out_mul; 24 void main(void) { 25 out_add = in_data + vec4(2.0, 3.0, 4.0, 5.0); 26 out_mul = in_data * vec4(2.0, 3.0, 4.0, 5.0); 27 } 28 </script> 29 <script> 30 "use strict"; 31 description(); 32 33 debug(""); 34 35 var wtu = WebGLTestUtils; 36 var gl = wtu.create3DContext(null, null, 2); 37 var program = null; 38 39 if (!gl) { 40 testFailed("WebGL context does not exist"); 41 } else { 42 testPassed("WebGL context exists"); 43 runTwoOutFeedbackTest(); 44 } 45 46 function doDrawWithTransformFeedback(expectedError, msg) { 47 gl.beginTransformFeedback(gl.POINTS); 48 wtu.glErrorShouldBe(gl, expectedError, msg); 49 gl.drawArrays(gl.POINTS, 0, 3); 50 gl.endTransformFeedback(); 51 gl.getError(); 52 } 53 54 function runTwoOutFeedbackTest() { 55 debug(""); 56 debug("Test binding the same buffer to two transform feedback binding points. Buffer should be untouched and an error should be generated.") 57 58 // Build the input and output buffers 59 var in_data = [ 60 1.0, 2.0, 3.0, 4.0, 61 2.0, 4.0, 8.0, 16.0, 62 0.75, 0.5, 0.25, 0.0 63 ]; 64 65 var in_buffer = gl.createBuffer(); 66 gl.bindBuffer(gl.ARRAY_BUFFER, in_buffer); 67 gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(in_data), gl.STATIC_DRAW); 68 69 // Create the transform feedback shader 70 program = wtu.setupTransformFeedbackProgram(gl, ["vshader", wtu.simpleColorFragmentShaderESSL300], 71 ["out_add", "out_mul"], gl.SEPARATE_ATTRIBS, 72 ["in_data"]); 73 wtu.glErrorShouldBe(gl, gl.NO_ERROR, "linking transform feedback shader should not set an error"); 74 shouldBeNonNull("program"); 75 76 // Draw the the transform feedback buffers 77 var tf = gl.createTransformFeedback(); 78 79 gl.enableVertexAttribArray(0); 80 gl.bindBuffer(gl.ARRAY_BUFFER, in_buffer); 81 gl.vertexAttribPointer(0, 4, gl.FLOAT, false, 16, 0); 82 83 var out_buffer = gl.createBuffer(); 84 var out_buffer2 = gl.createBuffer(); 85 gl.bindBuffer(gl.TRANSFORM_FEEDBACK_BUFFER, out_buffer); 86 87 // Test binding the same buffer to two transform feedback binding points with bindBufferBase. 88 debug(""); 89 gl.enable(gl.RASTERIZER_DISCARD); 90 gl.bufferData(gl.TRANSFORM_FEEDBACK_BUFFER, Float32Array.BYTES_PER_ELEMENT * in_data.length * 2, gl.STATIC_DRAW); 91 gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 0, out_buffer); 92 gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 1, out_buffer); 93 94 doDrawWithTransformFeedback(gl.INVALID_OPERATION, "same buffer bound to two transform feedback binding points with bindBufferBase"); 95 96 gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 0, null); 97 gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 1, null); 98 gl.disable(gl.RASTERIZER_DISCARD); 99 100 // Check buffer contents. 101 var expectedZeroes = []; 102 for (var i = 0; i < in_data.length * 2; ++i) 103 { 104 expectedZeroes.push(0.0); 105 } 106 gl.bindBuffer(gl.TRANSFORM_FEEDBACK_BUFFER, out_buffer); 107 debug("buffer should be untouched - filled with zeroes"); 108 wtu.checkFloatBuffer(gl, gl.TRANSFORM_FEEDBACK_BUFFER, expectedZeroes); 109 110 // Test binding the same buffer to two transform feedback binding points with bindBufferRange. The ranges overlap just slightly. 111 debug(""); 112 gl.enable(gl.RASTERIZER_DISCARD); 113 gl.bufferData(gl.TRANSFORM_FEEDBACK_BUFFER, Float32Array.BYTES_PER_ELEMENT * in_data.length * 2, gl.STATIC_DRAW); 114 gl.bindBufferRange(gl.TRANSFORM_FEEDBACK_BUFFER, 0, out_buffer, 0, in_data.length * 4); 115 gl.bindBufferRange(gl.TRANSFORM_FEEDBACK_BUFFER, 1, out_buffer, (in_data.length - 1) * 4, in_data.length * 4); 116 117 doDrawWithTransformFeedback(gl.INVALID_OPERATION, "same buffer bound to two transform feedback binding points with bindBufferRange, overlapping ranges"); 118 119 gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 0, null); 120 gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 1, null); 121 gl.disable(gl.RASTERIZER_DISCARD); 122 123 // Check buffer contents. 124 gl.bindBuffer(gl.TRANSFORM_FEEDBACK_BUFFER, out_buffer); 125 debug("buffer should be untouched - filled with zeroes"); 126 wtu.checkFloatBuffer(gl, gl.TRANSFORM_FEEDBACK_BUFFER, expectedZeroes); 127 128 // Test non-overlapping ranges. 129 debug(""); 130 gl.enable(gl.RASTERIZER_DISCARD); 131 gl.bufferData(gl.TRANSFORM_FEEDBACK_BUFFER, Float32Array.BYTES_PER_ELEMENT * in_data.length * 2, gl.STATIC_DRAW); 132 gl.bindBufferRange(gl.TRANSFORM_FEEDBACK_BUFFER, 0, out_buffer, 0, in_data.length * 4); 133 gl.bindBufferRange(gl.TRANSFORM_FEEDBACK_BUFFER, 1, out_buffer, in_data.length * 4, in_data.length * 4); 134 135 doDrawWithTransformFeedback(gl.INVALID_OPERATION, "same buffer bound to two transform feedback binding points with bindBufferRange, non-overlapping ranges"); 136 137 gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 0, null); 138 gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 1, null); 139 gl.disable(gl.RASTERIZER_DISCARD); 140 141 // Check buffer contents. 142 gl.bindBuffer(gl.TRANSFORM_FEEDBACK_BUFFER, out_buffer); 143 debug("buffer should be untouched - filled with zeroes"); 144 wtu.checkFloatBuffer(gl, gl.TRANSFORM_FEEDBACK_BUFFER, expectedZeroes); 145 146 // Test binding the same buffer to a binding point that doesn't have a corresponding output in the vertex shader. 147 debug(""); 148 gl.enable(gl.RASTERIZER_DISCARD); 149 gl.bindBuffer(gl.TRANSFORM_FEEDBACK_BUFFER, out_buffer2); 150 gl.bufferData(gl.TRANSFORM_FEEDBACK_BUFFER, Float32Array.BYTES_PER_ELEMENT * in_data.length * 2, gl.STATIC_DRAW); 151 gl.bindBuffer(gl.TRANSFORM_FEEDBACK_BUFFER, out_buffer); 152 gl.bufferData(gl.TRANSFORM_FEEDBACK_BUFFER, Float32Array.BYTES_PER_ELEMENT * in_data.length * 2, gl.STATIC_DRAW); 153 gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 0, out_buffer); 154 gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 1, out_buffer2); 155 gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 2, out_buffer); // No corresponding output. 156 157 doDrawWithTransformFeedback(gl.INVALID_OPERATION, "same buffer bound to two transform feedback binding points with bindBufferBase, but one of the binding points doesn't have a corresponding shader output"); 158 159 gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 0, null); 160 gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 1, null); 161 gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 2, null); 162 gl.disable(gl.RASTERIZER_DISCARD); 163 164 // Check buffer contents. 165 debug("buffers should be untouched - filled with zeroes"); 166 gl.bindBuffer(gl.TRANSFORM_FEEDBACK_BUFFER, out_buffer); 167 wtu.checkFloatBuffer(gl, gl.TRANSFORM_FEEDBACK_BUFFER, expectedZeroes); 168 gl.bindBuffer(gl.TRANSFORM_FEEDBACK_BUFFER, out_buffer2); 169 wtu.checkFloatBuffer(gl, gl.TRANSFORM_FEEDBACK_BUFFER, expectedZeroes); 170 171 finishTest(); 172 } 173 </script> 174 175 </body> 176 </html>