11import { Colors } from '../../../../common/util/colors.js' ;
22import { GPUTest } from '../../../gpu_test.js' ;
33
4+ /**
5+ * Options for runFlowControlTest()
6+ */
7+ interface FlowControlTest extends GPUTest {
8+ params : {
9+ /**
10+ * If true, then constant values will be placed into a storage buffer,
11+ * preventing the shader compiler from knowing the value at compile time.
12+ * This can prevent constant folding, loop unrolling, dead-code
13+ * optimizations etc, which would could all affect the tests.
14+ */
15+ preventValueOptimizations ?: boolean ;
16+ } ;
17+ }
18+
419/**
520 * The builder interface for the runFlowControlTest() callback.
6- * This interface is indented to be used to inject WGSL logic into the test shader.
21+ * This interface is indented to be used to inject WGSL logic into the test
22+ * shader.
723 * @see runFlowControlTest
824 */
925interface FlowControlTestBuilder {
1026 /**
11- * Emits an expression to load the given value from a storage buffer, preventing the shader
12- * compiler from knowing the value at compile time. This can prevent constant folding, loop
13- * unrolling, dead-code optimizations etc, which would could all affect the tests.
27+ * Emits a value into the shader.
28+ * If the FlowControlTest.params.preventValueOptimizations flag is enabled,
29+ * then value() emits an expression to load the given value from a storage
30+ * buffer, preventing the shader compiler from knowing the value at compile
31+ * time. This can prevent constant folding, loop unrolling, dead-code
32+ * optimizations etc, which would could all affect the tests.
1433 */
1534 value ( v : number | boolean ) : string ;
1635
1736 /**
18- * Emits an expectation that the statement will be executed at the given chronological events.
37+ * Emits an expectation that the statement will be executed at the given
38+ * chronological events.
1939 * @param event one or more chronological events, the first being 0.
2040 */
2141 expect_order ( ...event : number [ ] ) : string ;
@@ -55,12 +75,13 @@ interface FlowControlTestBuilder {
5575 * ```
5676 *
5777 * @param t The test object
58- * @param builder The shader builder function that takes a FlowControlTestBuilder as the single
59- * argument, and returns either a WGSL string which is embedded into the WGSL entrypoint function,
60- * or a structure with entrypoint-scoped WGSL code and extra module-scope WGSL code.
78+ * @param builder The shader builder function that takes a
79+ * FlowControlTestBuilder as the single argument, and returns either a WGSL
80+ * string which is embedded into the WGSL entrypoint function, or a structure
81+ * with entrypoint-scoped WGSL code and extra module-scope WGSL code.
6182 */
6283export function runFlowControlTest (
63- t : GPUTest ,
84+ t : FlowControlTest ,
6485 build_wgsl : ( builder : FlowControlTestBuilder ) => string | { entrypoint : string ; extra : string }
6586) {
6687 const inputData = new Array < number > ( ) ;
@@ -80,12 +101,16 @@ export function runFlowControlTest(
80101
81102 const build_wgsl_result = build_wgsl ( {
82103 value : v => {
83- if ( typeof v === 'boolean' ) {
84- inputData . push ( v ? 1 : 0 ) ;
85- return `inputs[${ inputData . length - 1 } ] != 0` ;
104+ if ( t . params . preventValueOptimizations ) {
105+ if ( typeof v === 'boolean' ) {
106+ inputData . push ( v ? 1 : 0 ) ;
107+ return `inputs[${ inputData . length - 1 } ] != 0` ;
108+ }
109+ inputData . push ( v ) ;
110+ return `inputs[${ inputData . length - 1 } ]` ;
111+ } else {
112+ return `${ v } ` ;
86113 }
87- inputData . push ( v ) ;
88- return `inputs[${ inputData . length - 1 } ]` ;
89114 } ,
90115 expect_order : ( ...expected ) => {
91116 expectations . push ( {
@@ -117,7 +142,7 @@ struct Outputs {
117142 count : u32,
118143 data : array<u32>,
119144};
120- @group(0) @binding(0) var<storage, read> inputs : array<u32 >;
145+ @group(0) @binding(0) var<storage, read> inputs : array<i32 >;
121146@group(0) @binding(1) var<storage, read_write> outputs : Outputs;
122147
123148fn push_output(value : u32) {
@@ -142,7 +167,8 @@ ${main_wgsl.extra}
142167 } ,
143168 } ) ;
144169
145- // If there are no inputs, just put a single value in the buffer to keep makeBufferWithContents() happy.
170+ // If there are no inputs, just put a single value in the buffer to keep
171+ // makeBufferWithContents() happy.
146172 if ( inputData . length === 0 ) {
147173 inputData . push ( 0 ) ;
148174 }
@@ -191,8 +217,8 @@ ${main_wgsl.extra}
191217 // returns an Error with the given message and WGSL source
192218 const fail = ( err : string ) => Error ( `${ err } \nWGSL:\n${ Colors . dim ( Colors . blue ( wgsl ) ) } ` ) ;
193219
194- // returns a colorized string of the expect_order() call, highlighting the event number that
195- // caused an error.
220+ // returns a colorized string of the expect_order() call, highlighting
221+ // the event number that caused an error.
196222 const expect_order_err = ( expectation : ExpectedEvents , err_idx : number ) => {
197223 let out = 'expect_order(' ;
198224 for ( let i = 0 ; i < expectation . values . length ; i ++ ) {
0 commit comments