@@ -46,9 +46,17 @@ type TexelViewComparer = {
4646 tableRows : ( failedCoords : readonly Required < GPUOrigin3DDict > [ ] ) => Iterable < string > [ ] ;
4747} ;
4848
49+ // Creates a texel view comparer that compares an actual texel view against
50+ // an expected texel view and optionally a second, alternate, texel view.
51+ // The comparison for each texel succeeds if the actual texel is close enough
52+ // to either
4953function makeTexelViewComparer (
5054 format : EncodableTextureFormat ,
51- { actTexelView, expTexelView } : { actTexelView : TexelView ; expTexelView : TexelView } ,
55+ {
56+ actTexelView,
57+ expTexelView,
58+ altExpTexelView,
59+ } : { actTexelView : TexelView ; expTexelView : TexelView ; altExpTexelView ?: TexelView } ,
5260 opts : TexelCompareOptions
5361) : TexelViewComparer {
5462 const {
@@ -76,27 +84,35 @@ function makeTexelViewComparer(
7684 const tvc = { } as TexelViewComparer ;
7785 if ( fmtIsInt ) {
7886 tvc . predicate = coords =>
79- comparePerComponent ( actTexelView . color ( coords ) , expTexelView . color ( coords ) , maxIntDiff ) ;
87+ comparePerComponent (
88+ actTexelView . color ( coords ) ,
89+ expTexelView . color ( coords ) ,
90+ maxIntDiff ,
91+ altExpTexelView ?. color ( coords )
92+ ) ;
8093 } else if ( fmtIsNorm && maxDiffULPsForNormFormat !== undefined ) {
8194 tvc . predicate = coords =>
8295 comparePerComponent (
8396 actTexelView . ulpFromZero ( coords ) ,
8497 expTexelView . ulpFromZero ( coords ) ,
85- maxDiffULPsForNormFormat
98+ maxDiffULPsForNormFormat ,
99+ altExpTexelView ?. ulpFromZero ( coords )
86100 ) ;
87101 } else if ( fmtIsFloat && maxDiffULPsForFloatFormat !== undefined ) {
88102 tvc . predicate = coords =>
89103 comparePerComponent (
90104 actTexelView . ulpFromZero ( coords ) ,
91105 expTexelView . ulpFromZero ( coords ) ,
92- maxDiffULPsForFloatFormat
106+ maxDiffULPsForFloatFormat ,
107+ altExpTexelView ?. ulpFromZero ( coords )
93108 ) ;
94109 } else if ( maxFractionalDiff !== undefined ) {
95110 tvc . predicate = coords =>
96111 comparePerComponent (
97112 actTexelView . color ( coords ) ,
98113 expTexelView . color ( coords ) ,
99- maxFractionalDiff
114+ maxFractionalDiff ,
115+ altExpTexelView ?. color ( coords )
100116 ) ;
101117 } else {
102118 if ( fmtIsNorm ) {
@@ -114,10 +130,17 @@ function makeTexelViewComparer(
114130 [ `tolerance ± ${ maxIntDiff } ` ] ,
115131 ( function * ( ) {
116132 yield * [ ` diff (act - exp)` , '==' , '' ] ;
133+ if ( altExpTexelView ) {
134+ yield * [ ` diff (act - alternateExp)` , '==' , '' ] ;
135+ }
117136 for ( const coords of failedCoords ) {
118137 const act = actTexelView . color ( coords ) ;
119138 const exp = expTexelView . color ( coords ) ;
120139 yield repr . componentOrder . map ( ch => act [ ch ] ! - exp [ ch ] ! ) . join ( ',' ) ;
140+ if ( altExpTexelView ) {
141+ const altExp = altExpTexelView . color ( coords ) ;
142+ yield repr . componentOrder . map ( ch => act [ ch ] ! - altExp [ ch ] ! ) . join ( ',' ) ;
143+ }
121144 }
122145 } ) ( ) ,
123146 ] ;
@@ -130,10 +153,17 @@ function makeTexelViewComparer(
130153 [ `tolerance ± ${ toleranceULPs } normal-ULPs` ] ,
131154 ( function * ( ) {
132155 yield * [ ` diff (act - exp) in normal-ULPs` , '==' , '' ] ;
156+ if ( altExpTexelView ) {
157+ yield * [ ` diff (act - alternateExp) in normal-ULPs` , '==' , '' ] ;
158+ }
133159 for ( const coords of failedCoords ) {
134160 const act = actTexelView . ulpFromZero ( coords ) ;
135161 const exp = expTexelView . ulpFromZero ( coords ) ;
136162 yield repr . componentOrder . map ( ch => act [ ch ] ! - exp [ ch ] ! ) . join ( ',' ) ;
163+ if ( altExpTexelView ) {
164+ const altExp = altExpTexelView . ulpFromZero ( coords ) ;
165+ yield repr . componentOrder . map ( ch => act [ ch ] ! - altExp [ ch ] ! ) . join ( ',' ) ;
166+ }
137167 }
138168 } ) ( ) ,
139169 ] ;
@@ -143,10 +173,17 @@ function makeTexelViewComparer(
143173 [ `tolerance ± ${ maxFractionalDiff } ` ] ,
144174 ( function * ( ) {
145175 yield * [ ` diff (act - exp)` , '==' , '' ] ;
176+ if ( altExpTexelView ) {
177+ yield * [ ` diff (act - alternateExp)` , '==' , '' ] ;
178+ }
146179 for ( const coords of failedCoords ) {
147180 const act = actTexelView . color ( coords ) ;
148181 const exp = expTexelView . color ( coords ) ;
149182 yield repr . componentOrder . map ( ch => ( act [ ch ] ! - exp [ ch ] ! ) . toPrecision ( 4 ) ) . join ( ',' ) ;
183+ if ( altExpTexelView ) {
184+ const altExp = altExpTexelView . color ( coords ) ;
185+ yield repr . componentOrder . map ( ch => ( act [ ch ] ! - altExp [ ch ] ! ) . toPrecision ( 4 ) ) . join ( ',' ) ;
186+ }
150187 }
151188 } ) ( ) ,
152189 ] ;
@@ -155,18 +192,32 @@ function makeTexelViewComparer(
155192 return tvc ;
156193}
157194
195+ /** Returns true if all components of an "actual" texel compare as
196+ * nearly equal (with tolerance) against either a (required) expected
197+ * texel or against an optional alternate texel.
198+ */
158199function comparePerComponent (
159200 actual : PerTexelComponent < number > ,
160201 expected : PerTexelComponent < number > ,
161- maxDiff : number
202+ maxDiff : number ,
203+ alternateExpected ?: PerTexelComponent < number >
162204) {
163- return Object . keys ( actual ) . every ( key => {
164- const k = key as TexelComponent ;
165- const act = actual [ k ] ! ;
166- const exp = expected [ k ] ;
167- if ( exp === undefined ) return false ;
168- return numbersApproximatelyEqual ( act , exp , maxDiff ) ;
169- } ) ;
205+ const similar = ( a : PerTexelComponent < number > , b : PerTexelComponent < number > , maxDiff : number ) =>
206+ Object . keys ( a ) . every ( key => {
207+ const k = key as TexelComponent ;
208+ const act = a [ k ] ! ;
209+ const exp = b [ k ] ;
210+ if ( exp === undefined ) return false ;
211+ return numbersApproximatelyEqual ( act , exp , maxDiff ) ;
212+ } ) ;
213+
214+ if ( similar ( actual , expected , maxDiff ) ) {
215+ return true ;
216+ }
217+ if ( alternateExpected ) {
218+ return similar ( actual , alternateExpected , maxDiff ) ;
219+ }
220+ return false ;
170221}
171222
172223/** Create a new mappable GPUBuffer, and copy a subrectangle of GPUTexture data into it. */
@@ -196,13 +247,17 @@ export function findFailedPixels(
196247 format : EncodableTextureFormat ,
197248 subrectOrigin : Required < GPUOrigin3DDict > ,
198249 subrectSize : Required < GPUExtent3DDict > ,
199- { actTexelView, expTexelView } : { actTexelView : TexelView ; expTexelView : TexelView } ,
250+ {
251+ actTexelView,
252+ expTexelView,
253+ altExpTexelView,
254+ } : { actTexelView : TexelView ; expTexelView : TexelView ; altExpTexelView ?: TexelView } ,
200255 texelCompareOptions : TexelCompareOptions ,
201256 coords ?: Generator < Required < GPUOrigin3DDict > >
202257) {
203258 const comparer = makeTexelViewComparer (
204259 format ,
205- { actTexelView, expTexelView } ,
260+ { actTexelView, expTexelView, altExpTexelView } ,
206261 texelCompareOptions
207262 ) ;
208263
@@ -260,6 +315,15 @@ export function findFailedPixels(
260315 yield `${ repr . componentOrder . map ( ch => numericToString ( pixel [ ch ] ! ) ) . join ( ',' ) } ` ;
261316 }
262317 } ) ( ) ;
318+ const printAlternateExpectedColors = ( function * ( ) {
319+ if ( altExpTexelView ) {
320+ yield * [ ' alternateExp. colors' , '==' , componentOrderStr ] ;
321+ for ( const coords of failedPixels ) {
322+ const pixel = altExpTexelView . color ( coords ) ;
323+ yield `${ repr . componentOrder . map ( ch => numericToString ( pixel [ ch ] ! ) ) . join ( ',' ) } ` ;
324+ }
325+ }
326+ } ) ( ) ;
263327 const printActualULPs = ( function * ( ) {
264328 yield * [ ' act. normal-ULPs-from-zero' , '==' , componentOrderStr ] ;
265329 for ( const coords of failedPixels ) {
@@ -274,6 +338,15 @@ export function findFailedPixels(
274338 yield `${ repr . componentOrder . map ( ch => pixel [ ch ] ) . join ( ',' ) } ` ;
275339 }
276340 } ) ( ) ;
341+ const printAlternateExpectedULPs = ( function * ( ) {
342+ if ( altExpTexelView ) {
343+ yield * [ ` alternateExp. normal-ULPs-from-zero` , '==' , componentOrderStr ] ;
344+ for ( const coords of failedPixels ) {
345+ const pixel = altExpTexelView . ulpFromZero ( coords ) ;
346+ yield `${ repr . componentOrder . map ( ch => pixel [ ch ] ) . join ( ',' ) } ` ;
347+ }
348+ }
349+ } ) ( ) ;
277350
278351 const opts = {
279352 fillToWidth : 120 ,
@@ -286,8 +359,10 @@ ${generatePrettyTable(opts, [
286359 printActualBytes ,
287360 printActualColors ,
288361 printExpectedColors ,
362+ printAlternateExpectedColors ,
289363 printActualULPs ,
290364 printExpectedULPs ,
365+ printAlternateExpectedULPs ,
291366 ...comparer . tableRows ( failedPixels ) ,
292367] ) } `;
293368}
0 commit comments