1
1
import { Colors } from '../../../../common/util/colors.js' ;
2
2
import { GPUTest } from '../../../gpu_test.js' ;
3
3
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
+
4
19
/**
5
20
* 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.
7
23
* @see runFlowControlTest
8
24
*/
9
25
interface FlowControlTestBuilder {
10
26
/**
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.
14
33
*/
15
34
value ( v : number | boolean ) : string ;
16
35
17
36
/**
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.
19
39
* @param event one or more chronological events, the first being 0.
20
40
*/
21
41
expect_order ( ...event : number [ ] ) : string ;
@@ -55,12 +75,13 @@ interface FlowControlTestBuilder {
55
75
* ```
56
76
*
57
77
* @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.
61
82
*/
62
83
export function runFlowControlTest (
63
- t : GPUTest ,
84
+ t : FlowControlTest ,
64
85
build_wgsl : ( builder : FlowControlTestBuilder ) => string | { entrypoint : string ; extra : string }
65
86
) {
66
87
const inputData = new Array < number > ( ) ;
@@ -80,12 +101,16 @@ export function runFlowControlTest(
80
101
81
102
const build_wgsl_result = build_wgsl ( {
82
103
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 } ` ;
86
113
}
87
- inputData . push ( v ) ;
88
- return `inputs[${ inputData . length - 1 } ]` ;
89
114
} ,
90
115
expect_order : ( ...expected ) => {
91
116
expectations . push ( {
@@ -117,7 +142,7 @@ struct Outputs {
117
142
count : u32,
118
143
data : array<u32>,
119
144
};
120
- @group(0) @binding(0) var<storage, read> inputs : array<u32 >;
145
+ @group(0) @binding(0) var<storage, read> inputs : array<i32 >;
121
146
@group(0) @binding(1) var<storage, read_write> outputs : Outputs;
122
147
123
148
fn push_output(value : u32) {
@@ -142,7 +167,8 @@ ${main_wgsl.extra}
142
167
} ,
143
168
} ) ;
144
169
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.
146
172
if ( inputData . length === 0 ) {
147
173
inputData . push ( 0 ) ;
148
174
}
@@ -191,8 +217,8 @@ ${main_wgsl.extra}
191
217
// returns an Error with the given message and WGSL source
192
218
const fail = ( err : string ) => Error ( `${ err } \nWGSL:\n${ Colors . dim ( Colors . blue ( wgsl ) ) } ` ) ;
193
219
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.
196
222
const expect_order_err = ( expectation : ExpectedEvents , err_idx : number ) => {
197
223
let out = 'expect_order(' ;
198
224
for ( let i = 0 ; i < expectation . values . length ; i ++ ) {
0 commit comments