Skip to content

Commit

Permalink
Merge branch 'main' into separate-rods
Browse files Browse the repository at this point in the history
  • Loading branch information
Kangz authored Jan 22, 2024
2 parents 42b1bee + 7528d64 commit 4b146e1
Show file tree
Hide file tree
Showing 22 changed files with 1,430 additions and 311 deletions.
4 changes: 3 additions & 1 deletion src/common/internal/file_loader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,15 +73,17 @@ export abstract class TestFileLoader extends EventTarget {
query: TestQuery,
{
subqueriesToExpand = [],
fullyExpandSubtrees = [],
maxChunkTime = Infinity,
}: { subqueriesToExpand?: string[]; maxChunkTime?: number } = {}
}: { subqueriesToExpand?: string[]; fullyExpandSubtrees?: string[]; maxChunkTime?: number } = {}
): Promise<TestTree> {
const tree = await loadTreeForQuery(this, query, {
subqueriesToExpand: subqueriesToExpand.map(s => {
const q = parseQuery(s);
assert(q.level >= 2, () => `subqueriesToExpand entries should not be multi-file:\n ${q}`);
return q;
}),
fullyExpandSubtrees: fullyExpandSubtrees.map(s => parseQuery(s)),
maxChunkTime,
});
this.dispatchEvent(new MessageEvent<void>('finish'));
Expand Down
7 changes: 6 additions & 1 deletion src/common/internal/tree.ts
Original file line number Diff line number Diff line change
Expand Up @@ -286,8 +286,9 @@ export async function loadTreeForQuery(
queryToLoad: TestQuery,
{
subqueriesToExpand,
fullyExpandSubtrees = [],
maxChunkTime = Infinity,
}: { subqueriesToExpand: TestQuery[]; maxChunkTime?: number }
}: { subqueriesToExpand: TestQuery[]; fullyExpandSubtrees?: TestQuery[]; maxChunkTime?: number }
): Promise<TestTree> {
const suite = queryToLoad.suite;
const specs = await loader.listing(suite);
Expand All @@ -303,6 +304,10 @@ export async function loadTreeForQuery(
// If toExpand == subquery, no expansion is needed (but it's still "seen").
if (ordering === Ordering.Equal) seenSubqueriesToExpand[i] = true;
return ordering !== Ordering.StrictSubset;
}) &&
fullyExpandSubtrees.every(toExpand => {
const ordering = compareQueries(toExpand, subquery);
return ordering === Ordering.Unordered;
});

// L0 = suite-level, e.g. suite:*
Expand Down
26 changes: 25 additions & 1 deletion src/common/runtime/helper/options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,30 @@ function getOptionsInfoFromSearchString<Type extends CTSOptions>(
return optionValues as unknown as Type;
}

/**
* converts foo/bar/src/webgpu/this/that/file.spec.ts to webgpu:this,that,file,*
*/
function convertPathToQuery(path: string) {
// removes .spec.ts and splits by directory separators.
const parts = path.substring(0, path.length - 8).split(/\/|\\/g);
// Gets parts only after the last `src`. Example: returns ['webgpu', 'foo', 'bar', 'test']
// for ['Users', 'me', 'src', 'cts', 'src', 'webgpu', 'foo', 'bar', 'test']
const partsAfterSrc = parts.slice(parts.lastIndexOf('src') + 1);
const suite = partsAfterSrc.shift();
return `${suite}:${partsAfterSrc.join(',')},*`;
}

/**
* If a query looks like a path (ends in .spec.ts and has directory separators)
* then convert try to convert it to a query.
*/
function convertPathLikeToQuery(queryOrPath: string) {
return queryOrPath.endsWith('.spec.ts') &&
(queryOrPath.includes('/') || queryOrPath.includes('\\'))
? convertPathToQuery(queryOrPath)
: queryOrPath;
}

/**
* Given a test query string in the form of `suite:foo,bar,moo&opt1=val1&opt2=val2
* returns the query and the options.
Expand All @@ -115,7 +139,7 @@ export function parseSearchParamLikeWithOptions<Type extends CTSOptions>(
options: Type;
} {
const searchString = query.includes('q=') || query.startsWith('?') ? query : `q=${query}`;
const queries = new URLSearchParams(searchString).getAll('q');
const queries = new URLSearchParams(searchString).getAll('q').map(convertPathLikeToQuery);
const options = getOptionsInfoFromSearchString(optionsInfos, searchString);
return { queries, options };
}
Expand Down
103 changes: 73 additions & 30 deletions src/common/tools/gen_wpt_cts_html.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,13 @@ interface ConfigJSON {
/** The prefix to trim from every line of the expectations_file. */
prefix: string;
};
/** Expend all subtrees for provided queries */
fullyExpandSubtrees?: {
file: string;
prefix: string;
};
/*No long path assert */
noLongPathAssert?: boolean;
}

interface Config {
Expand All @@ -79,10 +86,15 @@ interface Config {
template: string;
maxChunkTimeMS: number;
argumentsPrefixes: string[];
noLongPathAssert: boolean;
expectations?: {
file: string;
prefix: string;
};
fullyExpandSubtrees?: {
file: string;
prefix: string;
};
}

let config: Config;
Expand All @@ -101,13 +113,20 @@ let config: Config;
template: path.resolve(jsonFileDir, configJSON.template),
maxChunkTimeMS: configJSON.maxChunkTimeMS ?? Infinity,
argumentsPrefixes: configJSON.argumentsPrefixes ?? ['?q='],
noLongPathAssert: configJSON.noLongPathAssert ?? false,
};
if (configJSON.expectations) {
config.expectations = {
file: path.resolve(jsonFileDir, configJSON.expectations.file),
prefix: configJSON.expectations.prefix,
};
}
if (configJSON.fullyExpandSubtrees) {
config.fullyExpandSubtrees = {
file: path.resolve(jsonFileDir, configJSON.fullyExpandSubtrees.file),
prefix: configJSON.fullyExpandSubtrees.prefix,
};
}
break;
}
case 4:
Expand All @@ -130,6 +149,7 @@ let config: Config;
suite,
maxChunkTimeMS: Infinity,
argumentsPrefixes: ['?q='],
noLongPathAssert: false,
};
if (process.argv.length >= 7) {
config.argumentsPrefixes = (await fs.readFile(argsPrefixesFile, 'utf8'))
Expand All @@ -153,36 +173,24 @@ let config: Config;
config.argumentsPrefixes.sort((a, b) => b.length - a.length);

// Load expectations (if any)
let expectationLines = new Set<string>();
if (config.expectations) {
expectationLines = new Set(
(await fs.readFile(config.expectations.file, 'utf8')).split(/\r?\n/).filter(l => l.length)
);
}
const expectations: Map<string, string[]> = await loadQueryFile(
config.argumentsPrefixes,
config.expectations
);

const expectations: Map<string, string[]> = new Map();
for (const prefix of config.argumentsPrefixes) {
expectations.set(prefix, []);
}

expLoop: for (const exp of expectationLines) {
// Take each expectation for the longest prefix it matches.
for (const argsPrefix of config.argumentsPrefixes) {
const prefix = config.expectations!.prefix + argsPrefix;
if (exp.startsWith(prefix)) {
expectations.get(argsPrefix)!.push(exp.substring(prefix.length));
continue expLoop;
}
}
console.log('note: ignored expectation: ' + exp);
}
// Load fullyExpandSubtrees queries (if any)
const fullyExpand: Map<string, string[]> = await loadQueryFile(
config.argumentsPrefixes,
config.fullyExpandSubtrees
);

const loader = new DefaultTestFileLoader();
const lines = [];
for (const prefix of config.argumentsPrefixes) {
const rootQuery = new TestQueryMultiFile(config.suite, []);
const tree = await loader.loadTree(rootQuery, {
subqueriesToExpand: expectations.get(prefix),
fullyExpandSubtrees: fullyExpand.get(prefix),
maxChunkTime: config.maxChunkTimeMS,
});

Expand All @@ -199,19 +207,21 @@ let config: Config;
alwaysExpandThroughLevel,
})) {
assert(query instanceof TestQueryMultiCase);
const queryString = query.toString();
// Check for a safe-ish path length limit. Filename must be <= 255, and on Windows the whole
// path must be <= 259. Leave room for e.g.:
// 'c:\b\s\w\xxxxxxxx\layout-test-results\external\wpt\webgpu\cts_worker=0_q=...-actual.txt'
assert(
queryString.length < 185,
`Generated test variant would produce too-long -actual.txt filename. Possible solutions:
if (!config.noLongPathAssert) {
const queryString = query.toString();
// Check for a safe-ish path length limit. Filename must be <= 255, and on Windows the whole
// path must be <= 259. Leave room for e.g.:
// 'c:\b\s\w\xxxxxxxx\layout-test-results\external\wpt\webgpu\cts_worker=0_q=...-actual.txt'
assert(
queryString.length < 185,
`Generated test variant would produce too-long -actual.txt filename. Possible solutions:
- Reduce the length of the parts of the test query
- Reduce the parameterization of the test
- Make the test function faster and regenerate the listing_meta entry
- Reduce the specificity of test expectations (if you're using them)
${queryString}`
);
);
}

lines.push({
urlQueryString: prefix + query.toString(), // "?worker=0&q=..."
Expand All @@ -232,6 +242,39 @@ ${queryString}`
process.exit(1);
});

async function loadQueryFile(
argumentsPrefixes: string[],
queryFile?: {
file: string;
prefix: string;
}
): Promise<Map<string, string[]>> {
let lines = new Set<string>();
if (queryFile) {
lines = new Set(
(await fs.readFile(queryFile.file, 'utf8')).split(/\r?\n/).filter(l => l.length)
);
}

const result: Map<string, string[]> = new Map();
for (const prefix of argumentsPrefixes) {
result.set(prefix, []);
}

expLoop: for (const exp of lines) {
// Take each expectation for the longest prefix it matches.
for (const argsPrefix of argumentsPrefixes) {
const prefix = queryFile!.prefix + argsPrefix;
if (exp.startsWith(prefix)) {
result.get(argsPrefix)!.push(exp.substring(prefix.length));
continue expLoop;
}
}
console.log('note: ignored expectation: ' + exp);
}
return result;
}

async function generateFile(
lines: Array<{ urlQueryString?: string; comment?: string } | undefined>
): Promise<void> {
Expand Down
41 changes: 36 additions & 5 deletions src/resources/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ ffmpeg.exe -loop 1 -i .\four-colors.png -c:v libvpx -pix_fmt yuv420p -frames 50
// Generate four-colors-theora-bt601.ogv, mimeType: 'video/ogg; codecs=theora'
ffmpeg.exe -loop 1 -i .\four-colors.png -c:v libtheora -pix_fmt yuv420p -frames 50 -colorspace smpte170m -color_primaries smpte170m -color_trc smpte170m -color_range tv four-colors-theora-bt601.ogv
// Generate four-colors-h264-bt601.mp4, mimeType: 'video/mp4; codecs=h264'
// Generate four-colors-h264-bt601.mp4, mimeType: 'video/mp4; codecs=avc1.4d400c'
ffmpeg.exe -loop 1 -i .\four-colors.png -c:v libx264 -pix_fmt yuv420p -frames 50 -colorspace smpte170m -color_primaries smpte170m -color_trc smpte170m -color_range tv four-colors-h264-bt601.mp4
// Generate four-colors-vp9-bt601.webm, mimeType: 'video/webm; codecs=vp9'
Expand All @@ -28,17 +28,17 @@ Use ffmepg to rotate video content x degrees in cw direction (by using `transpos

H264 rotated video files are generated by ffmpeg cmds below:
```
// Generate four-colors-h264-bt601-rotate-90.mp4, mimeType: 'video/mp4; codecs=h264'
// Generate four-colors-h264-bt601-rotate-90.mp4, mimeType: 'video/mp4; codecs=avc1.4d400c'
ffmpeg.exe -loop 1 -i .\four-colors.png -c:v libx264 -pix_fmt yuv420p -frames 50 -colorspace smpte170m -color_primaries smpte170m -color_trc smpte170m -color_range tv -vf transpose=2 temp.mp4
ffmpeg -display_rotation 270 -i temp.mp4 -c copy four-colors-h264-bt601-rotate-90.mp4
rm temp.mp4
// Generate four-colors-h264-bt601-rotate-180.mp4, mimeType: 'video/mp4; codecs=h264'
// Generate four-colors-h264-bt601-rotate-180.mp4, mimeType: 'video/mp4; codecs=avc1.4d400c'
ffmpeg.exe -loop 1 -i .\four-colors.png -c:v libx264 -pix_fmt yuv420p -frames 50 -colorspace smpte170m -color_primaries smpte170m -color_trc smpte170m -color_range tv -vf transpose=2,transpose=2 temp.mp4
ffmpeg -display_rotation 180 -i temp.mp4 -c copy four-colors-h264-bt601-rotate-180.mp4
rm temp.mp4
// Generate four-colors-h264-bt601-rotate-270.mp4, mimeType: 'video/mp4; codecs=h264'
// Generate four-colors-h264-bt601-rotate-270.mp4, mimeType: 'video/mp4; codecs=avc1.4d400c'
ffmpeg.exe -loop 1 -i .\four-colors.png -c:v libx264 -pix_fmt yuv420p -frames 50 -colorspace smpte170m -color_primaries smpte170m -color_trc smpte170m -color_range tv -vf transpose=1 temp.mp4
ffmpeg -display_rotation 90 -i temp.mp4 -c copy four-colors-h264-bt601-rotate-270.mp4
rm temp.mp4
Expand All @@ -62,4 +62,35 @@ ffmpeg.exe -loop 1 -i .\four-colors.png -c:v libvpx-vp9 -pix_fmt yuv420p -frames
ffmpeg -display_rotation 90 -i temp.mp4 -c copy four-colors-vp9-bt601-rotate-270.mp4
rm temp.mp4
```
```

Generate video files to test flip behaviour.
Use ffmpeg to flip video content. Using `display_hflip` to do horizontal flip and `display_vflip` to do vertical flip.

H264 flip video files are generated by ffmpeg cmds below:
```
// Generate four-colors-h264-bt601-hflip.mp4, mimeType: 'video/mp4; codecs=avc1.4d400c'
ffmpeg.exe -loop 1 -i .\four-colors.png -c:v libx264 -pix_fmt yuv420p -frames 50 -colorspace smpte170m -color_primaries smpte170m -color_trc smpte170m -color_range tv temp.mp4
ffmpeg -display_hflip -i temp.mp4 -c copy four-colors-h264-bt601-hflip.mp4
rm temp.mp4
// Generate four-colors-h264-bt601-vflip.mp4, mimeType: 'video/mp4; codecs=avc1.4d400c'
ffmpeg.exe -loop 1 -i .\four-colors.png -c:v libx264 -pix_fmt yuv420p -frames 50 -colorspace smpte170m -color_primaries smpte170m -color_trc smpte170m -color_range tv temp.mp4
ffmpeg -display_vflip -i temp.mp4 -c copy four-colors-h264-bt601-vflip.mp4
rm temp.mp4
```

Vp9 flip video files are generated by ffmpeg cmds below:
```
// Generate four-colors-vp9-bt601-hflip.mp4, mimeType: 'video/mp4; codecs=vp09.00.10.08'
ffmpeg.exe -loop 1 -i .\four-colors.png -c:v libvpx-vp9 -pix_fmt yuv420p -frames 50 -colorspace smpte170m -color_primaries smpte170m -color_trc smpte170m -color_range tv temp.mp4
ffmpeg -display_hflip -i temp.mp4 -c copy four-colors-vp9-bt601-hflip.mp4
rm temp.mp4
// Generate four-colors-vp9-bt601-vflip.mp4, mimeType: 'video/mp4; codecs=vp09.00.10.08'
ffmpeg.exe -loop 1 -i .\four-colors.png -c:v libvpx-vp9 -pix_fmt yuv420p -frames 50 -colorspace smpte170m -color_primaries smpte170m -color_trc smpte170m -color_range tv temp.mp4
ffmpeg -display_vflip -i temp.mp4 -c copy four-colors-vp9-bt601-vflip.mp4
rm temp.mp4
```
Loading

0 comments on commit 4b146e1

Please sign in to comment.