xref: /aosp_15_r20/external/deqp/scripts/check_swiftshader_runtime.py (revision 35238bce31c2a825756842865a792f8cf7f89930)
1*35238bceSAndroid Build Coastguard Worker# Copyright 2021 Google LLC.
2*35238bceSAndroid Build Coastguard Worker# Copyright 2021 The Khronos Group Inc.
3*35238bceSAndroid Build Coastguard Worker#
4*35238bceSAndroid Build Coastguard Worker# Licensed under the Apache License, Version 2.0 (the "License");
5*35238bceSAndroid Build Coastguard Worker# you may not use this file except in compliance with the License.
6*35238bceSAndroid Build Coastguard Worker# You may obtain a copy of the License at
7*35238bceSAndroid Build Coastguard Worker#
8*35238bceSAndroid Build Coastguard Worker#     https://www.apache.org/licenses/LICENSE-2.0
9*35238bceSAndroid Build Coastguard Worker#
10*35238bceSAndroid Build Coastguard Worker# Unless required by applicable law or agreed to in writing, software
11*35238bceSAndroid Build Coastguard Worker# distributed under the License is distributed on an "AS IS" BASIS,
12*35238bceSAndroid Build Coastguard Worker# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*35238bceSAndroid Build Coastguard Worker# See the License for the specific language governing permissions and
14*35238bceSAndroid Build Coastguard Worker# limitations under the License.
15*35238bceSAndroid Build Coastguard Worker
16*35238bceSAndroid Build Coastguard Worker# Requirements to run the script:
17*35238bceSAndroid Build Coastguard Worker# - Python3 (apt-get install -y python3.x)
18*35238bceSAndroid Build Coastguard Worker# - GO      (apt-get install -y golang-go)
19*35238bceSAndroid Build Coastguard Worker# - cmake   (version 3.13 or later)
20*35238bceSAndroid Build Coastguard Worker# - ninja   (apt-get install -y ninja-build)
21*35238bceSAndroid Build Coastguard Worker# - git     (sudo apt-get install -y git)
22*35238bceSAndroid Build Coastguard Worker
23*35238bceSAndroid Build Coastguard Worker# GO dependencies needed:
24*35238bceSAndroid Build Coastguard Worker# - crypto/openpgp (go get -u golang.org/x/crypto/openpgp...)
25*35238bceSAndroid Build Coastguard Worker
26*35238bceSAndroid Build Coastguard Workerimport os
27*35238bceSAndroid Build Coastguard Workerimport json
28*35238bceSAndroid Build Coastguard Workerimport tempfile
29*35238bceSAndroid Build Coastguard Workerimport subprocess
30*35238bceSAndroid Build Coastguard Workerimport sys
31*35238bceSAndroid Build Coastguard Worker
32*35238bceSAndroid Build Coastguard Workerfrom argparse import ArgumentParser
33*35238bceSAndroid Build Coastguard Workerfrom shutil import which, copyfile
34*35238bceSAndroid Build Coastguard Workerfrom pathlib import Path
35*35238bceSAndroid Build Coastguard Workerfrom datetime import datetime
36*35238bceSAndroid Build Coastguard Worker
37*35238bceSAndroid Build Coastguard Worker# Check for correct python version (python3) before doing anything.
38*35238bceSAndroid Build Coastguard Workerif sys.version_info.major < 3:
39*35238bceSAndroid Build Coastguard Worker        raise RuntimeError("Python version needs to be 3 or greater.")
40*35238bceSAndroid Build Coastguard Worker
41*35238bceSAndroid Build Coastguard WorkerAP = ArgumentParser()
42*35238bceSAndroid Build Coastguard WorkerAP.add_argument(
43*35238bceSAndroid Build Coastguard Worker    "-d",
44*35238bceSAndroid Build Coastguard Worker    "--directory",
45*35238bceSAndroid Build Coastguard Worker    metavar="DIRECTORY",
46*35238bceSAndroid Build Coastguard Worker    type=str,
47*35238bceSAndroid Build Coastguard Worker    help="Path to directory that will be used as root for cloning and file saving.",
48*35238bceSAndroid Build Coastguard Worker    default=str(Path(tempfile.gettempdir()) / "deqp-swiftshader")
49*35238bceSAndroid Build Coastguard Worker)
50*35238bceSAndroid Build Coastguard WorkerAP.add_argument(
51*35238bceSAndroid Build Coastguard Worker    "-u",
52*35238bceSAndroid Build Coastguard Worker    "--url",
53*35238bceSAndroid Build Coastguard Worker    metavar="URL",
54*35238bceSAndroid Build Coastguard Worker    type=str,
55*35238bceSAndroid Build Coastguard Worker    help="URL of SwiftShader Git repository.",
56*35238bceSAndroid Build Coastguard Worker    default="https://swiftshader.googlesource.com/SwiftShader",
57*35238bceSAndroid Build Coastguard Worker)
58*35238bceSAndroid Build Coastguard WorkerAP.add_argument(
59*35238bceSAndroid Build Coastguard Worker    "-l",
60*35238bceSAndroid Build Coastguard Worker    "--vlayer_url",
61*35238bceSAndroid Build Coastguard Worker    metavar="VURL",
62*35238bceSAndroid Build Coastguard Worker    type=str,
63*35238bceSAndroid Build Coastguard Worker    help="URL of Validation Layers Git repository.",
64*35238bceSAndroid Build Coastguard Worker    default="https://github.com/KhronosGroup/Vulkan-ValidationLayers.git",
65*35238bceSAndroid Build Coastguard Worker)
66*35238bceSAndroid Build Coastguard WorkerAP.add_argument(
67*35238bceSAndroid Build Coastguard Worker    "-b",
68*35238bceSAndroid Build Coastguard Worker    "--sws_build_type",
69*35238bceSAndroid Build Coastguard Worker    metavar="SWS_BUILD_TYPE",
70*35238bceSAndroid Build Coastguard Worker    type=str,
71*35238bceSAndroid Build Coastguard Worker    help="SwiftShader build type.",
72*35238bceSAndroid Build Coastguard Worker    choices=["debug", "release"],
73*35238bceSAndroid Build Coastguard Worker    default="debug",
74*35238bceSAndroid Build Coastguard Worker)
75*35238bceSAndroid Build Coastguard WorkerAP.add_argument(
76*35238bceSAndroid Build Coastguard Worker    "-q",
77*35238bceSAndroid Build Coastguard Worker    "--deqp_vk",
78*35238bceSAndroid Build Coastguard Worker    metavar="DEQP_VK",
79*35238bceSAndroid Build Coastguard Worker    type=str,
80*35238bceSAndroid Build Coastguard Worker    help="Path to deqp-vk binary.",
81*35238bceSAndroid Build Coastguard Worker)
82*35238bceSAndroid Build Coastguard WorkerAP.add_argument(
83*35238bceSAndroid Build Coastguard Worker    "-v",
84*35238bceSAndroid Build Coastguard Worker    "--vk_gl_cts",
85*35238bceSAndroid Build Coastguard Worker    metavar="VK_GL_CTS",
86*35238bceSAndroid Build Coastguard Worker    type=str,
87*35238bceSAndroid Build Coastguard Worker    help="Path to vk-gl-cts source directory.",
88*35238bceSAndroid Build Coastguard Worker)
89*35238bceSAndroid Build Coastguard WorkerAP.add_argument(
90*35238bceSAndroid Build Coastguard Worker    "-w",
91*35238bceSAndroid Build Coastguard Worker    "--vk_gl_cts_build",
92*35238bceSAndroid Build Coastguard Worker    metavar="VK_GL_CTS_BUILD",
93*35238bceSAndroid Build Coastguard Worker    type=str,
94*35238bceSAndroid Build Coastguard Worker    help="Path to vk-gl-cts build directory.",
95*35238bceSAndroid Build Coastguard Worker    default=str(Path(tempfile.gettempdir()) / "deqp-swiftshader" / "vk-gl-cts-build"),
96*35238bceSAndroid Build Coastguard Worker)
97*35238bceSAndroid Build Coastguard WorkerAP.add_argument(
98*35238bceSAndroid Build Coastguard Worker    "-t",
99*35238bceSAndroid Build Coastguard Worker    "--vk_gl_cts_build_type",
100*35238bceSAndroid Build Coastguard Worker    metavar="VK_GL_CTS_BUILD_TYPE",
101*35238bceSAndroid Build Coastguard Worker    type=str,
102*35238bceSAndroid Build Coastguard Worker    help="vk-gl-cts build type.",
103*35238bceSAndroid Build Coastguard Worker    choices=["debug", "release"],
104*35238bceSAndroid Build Coastguard Worker    default="debug",
105*35238bceSAndroid Build Coastguard Worker)
106*35238bceSAndroid Build Coastguard WorkerAP.add_argument(
107*35238bceSAndroid Build Coastguard Worker    "-r",
108*35238bceSAndroid Build Coastguard Worker    "--recipe",
109*35238bceSAndroid Build Coastguard Worker    metavar="RECIPE",
110*35238bceSAndroid Build Coastguard Worker    type=str,
111*35238bceSAndroid Build Coastguard Worker    help="Recipes to only run parts of script.",
112*35238bceSAndroid Build Coastguard Worker    choices=["run-deqp", "check-comparison"],
113*35238bceSAndroid Build Coastguard Worker    default="run-deqp",
114*35238bceSAndroid Build Coastguard Worker)
115*35238bceSAndroid Build Coastguard WorkerAP.add_argument(
116*35238bceSAndroid Build Coastguard Worker    "-f",
117*35238bceSAndroid Build Coastguard Worker    "--files",
118*35238bceSAndroid Build Coastguard Worker    nargs=2,
119*35238bceSAndroid Build Coastguard Worker    metavar=("NEWER_FILE_PATH", "OLDER_FILE_PATH"),
120*35238bceSAndroid Build Coastguard Worker    type=str,
121*35238bceSAndroid Build Coastguard Worker    help="Compare two different run results.",
122*35238bceSAndroid Build Coastguard Worker)
123*35238bceSAndroid Build Coastguard WorkerAP.add_argument(
124*35238bceSAndroid Build Coastguard Worker    "-a",
125*35238bceSAndroid Build Coastguard Worker    "--validation",
126*35238bceSAndroid Build Coastguard Worker    metavar="VALIDATION",
127*35238bceSAndroid Build Coastguard Worker    type=str,
128*35238bceSAndroid Build Coastguard Worker    help="Enable vulkan validation layers.",
129*35238bceSAndroid Build Coastguard Worker    choices=["true", "false"],
130*35238bceSAndroid Build Coastguard Worker    default="false",
131*35238bceSAndroid Build Coastguard Worker)
132*35238bceSAndroid Build Coastguard WorkerAP.add_argument(
133*35238bceSAndroid Build Coastguard Worker    "-o",
134*35238bceSAndroid Build Coastguard Worker    "--result_output",
135*35238bceSAndroid Build Coastguard Worker    metavar="OUTPUT",
136*35238bceSAndroid Build Coastguard Worker    type=str,
137*35238bceSAndroid Build Coastguard Worker    help="Filename of the regres results.",
138*35238bceSAndroid Build Coastguard Worker    default=str("result_" + str(datetime.now().strftime('%m_%d_%Y_%H_%M_%S')) + ".json"),
139*35238bceSAndroid Build Coastguard Worker)
140*35238bceSAndroid Build Coastguard Worker
141*35238bceSAndroid Build Coastguard WorkerARGS = AP.parse_args()
142*35238bceSAndroid Build Coastguard Worker
143*35238bceSAndroid Build Coastguard Worker# Check that we have everything needed to run the script when using recipe run-deqp.
144*35238bceSAndroid Build Coastguard Workerif ARGS.recipe == "run-deqp":
145*35238bceSAndroid Build Coastguard Worker    if which("go") is None:
146*35238bceSAndroid Build Coastguard Worker        raise RuntimeError("go not found. (apt-get install -y golang-go)")
147*35238bceSAndroid Build Coastguard Worker    if which("cmake") is None:
148*35238bceSAndroid Build Coastguard Worker        raise RuntimeError("CMake not found. (version 3.13 or later needed)")
149*35238bceSAndroid Build Coastguard Worker    if which("ninja") is None:
150*35238bceSAndroid Build Coastguard Worker        raise RuntimeError("Ninja not found. (apt-get install -y ninja-build)")
151*35238bceSAndroid Build Coastguard Worker    if which("git") is None:
152*35238bceSAndroid Build Coastguard Worker        raise RuntimeError("Git not found. (apt-get install -y git)")
153*35238bceSAndroid Build Coastguard Worker    if ARGS.vk_gl_cts is None:
154*35238bceSAndroid Build Coastguard Worker        raise RuntimeError("vk-gl-cts source directory must be provided. Use --help for more info.")
155*35238bceSAndroid Build Coastguard Worker
156*35238bceSAndroid Build Coastguard WorkerPARENT_DIR = Path(ARGS.directory).resolve()
157*35238bceSAndroid Build Coastguard Worker
158*35238bceSAndroid Build Coastguard WorkerSWS_SRC_DIR = PARENT_DIR / "SwiftShader"
159*35238bceSAndroid Build Coastguard WorkerSWS_BUILD_DIR = SWS_SRC_DIR / "build"
160*35238bceSAndroid Build Coastguard WorkerSWIFTSHADER_URL = ARGS.url
161*35238bceSAndroid Build Coastguard Worker
162*35238bceSAndroid Build Coastguard WorkerLAYERS_PARENT_DIR = Path(ARGS.directory).resolve()
163*35238bceSAndroid Build Coastguard WorkerLAYERS_SRC_DIR = LAYERS_PARENT_DIR / "Vulkan_Validation_Layers"
164*35238bceSAndroid Build Coastguard WorkerLAYERS_URL = ARGS.vlayer_url
165*35238bceSAndroid Build Coastguard WorkerLAYERS_BUILD_DIR = LAYERS_SRC_DIR / "build"
166*35238bceSAndroid Build Coastguard Worker
167*35238bceSAndroid Build Coastguard WorkerLINUX_SWS_ICD_DIR = SWS_BUILD_DIR / "Linux"
168*35238bceSAndroid Build Coastguard WorkerREGRES_DIR = SWS_SRC_DIR / "tests" / "regres"
169*35238bceSAndroid Build Coastguard WorkerRESULT_DIR = PARENT_DIR / "regres_results"
170*35238bceSAndroid Build Coastguard WorkerCOMP_RESULTS_DIR = PARENT_DIR / "comparison_results"
171*35238bceSAndroid Build Coastguard Worker
172*35238bceSAndroid Build Coastguard WorkerVK_GL_CTS_ROOT_DIR = Path(ARGS.vk_gl_cts)
173*35238bceSAndroid Build Coastguard WorkerVK_GL_CTS_BUILD_DIR = Path(ARGS.vk_gl_cts_build)
174*35238bceSAndroid Build Coastguard WorkerMUSTPASS_LIST = VK_GL_CTS_ROOT_DIR / "external" / "vulkancts" / "mustpass" / "main" / "vk-default.txt"
175*35238bceSAndroid Build Coastguard Workerif ARGS.deqp_vk is None:
176*35238bceSAndroid Build Coastguard Worker    DEQP_VK_BINARY = VK_GL_CTS_BUILD_DIR / "external" / "vulkancts" / "modules" / "vulkan" / "deqp-vk"
177*35238bceSAndroid Build Coastguard Workerelse:
178*35238bceSAndroid Build Coastguard Worker    DEQP_VK_BINARY = str(ARGS.deqp_vk)
179*35238bceSAndroid Build Coastguard Worker
180*35238bceSAndroid Build Coastguard Workernew_pass = []
181*35238bceSAndroid Build Coastguard Workernew_fail = []
182*35238bceSAndroid Build Coastguard Workernew_crash = []
183*35238bceSAndroid Build Coastguard Workernew_notsupported = []
184*35238bceSAndroid Build Coastguard Workerhas_been_removed = []
185*35238bceSAndroid Build Coastguard Workerstatus_change = []
186*35238bceSAndroid Build Coastguard Workercompatibility_warning = []
187*35238bceSAndroid Build Coastguard Workerquality_warning = []
188*35238bceSAndroid Build Coastguard Workerinternal_errors = []
189*35238bceSAndroid Build Coastguard Workerwaivers = []
190*35238bceSAndroid Build Coastguard Worker
191*35238bceSAndroid Build Coastguard Workerclass Result:
192*35238bceSAndroid Build Coastguard Worker    def __init__(self, filename):
193*35238bceSAndroid Build Coastguard Worker        self.filename = filename
194*35238bceSAndroid Build Coastguard Worker        self.f = open(filename)
195*35238bceSAndroid Build Coastguard Worker        # Skip the first four lines and check that the file order has not been changed.
196*35238bceSAndroid Build Coastguard Worker        tmp = ""
197*35238bceSAndroid Build Coastguard Worker        for i in range(4):
198*35238bceSAndroid Build Coastguard Worker            tmp = tmp + self.f.readline()
199*35238bceSAndroid Build Coastguard Worker        if "Tests" not in tmp:
200*35238bceSAndroid Build Coastguard Worker            raise RuntimeError("Skipped four lines, no starting line found. Has the file order changed?")
201*35238bceSAndroid Build Coastguard Worker
202*35238bceSAndroid Build Coastguard Worker    # Reads one test item from the file.
203*35238bceSAndroid Build Coastguard Worker    def readResult(self):
204*35238bceSAndroid Build Coastguard Worker        while True:
205*35238bceSAndroid Build Coastguard Worker            tmp = ""
206*35238bceSAndroid Build Coastguard Worker            while "}" not in tmp:
207*35238bceSAndroid Build Coastguard Worker                tmp = tmp + self.f.readline()
208*35238bceSAndroid Build Coastguard Worker            if "Test" in tmp:
209*35238bceSAndroid Build Coastguard Worker                tmp = tmp[tmp.find("{") : tmp.find("}") + 1]
210*35238bceSAndroid Build Coastguard Worker                return json.loads(tmp)
211*35238bceSAndroid Build Coastguard Worker            else:
212*35238bceSAndroid Build Coastguard Worker                return None
213*35238bceSAndroid Build Coastguard Worker
214*35238bceSAndroid Build Coastguard Worker    # Search for a test name. Returns the test data if found and otherwise False.
215*35238bceSAndroid Build Coastguard Worker    def searchTest(self, test):
216*35238bceSAndroid Build Coastguard Worker        line = self.f.readline()
217*35238bceSAndroid Build Coastguard Worker        while line:
218*35238bceSAndroid Build Coastguard Worker            if line.find(test) != -1:
219*35238bceSAndroid Build Coastguard Worker                # Found the test.
220*35238bceSAndroid Build Coastguard Worker                while "}" not in line:
221*35238bceSAndroid Build Coastguard Worker                    line = line + self.f.readline()
222*35238bceSAndroid Build Coastguard Worker
223*35238bceSAndroid Build Coastguard Worker                line = line[line.find("{") : line.find("}") + 1]
224*35238bceSAndroid Build Coastguard Worker                return json.loads(line)
225*35238bceSAndroid Build Coastguard Worker            line = self.f.readline()
226*35238bceSAndroid Build Coastguard Worker
227*35238bceSAndroid Build Coastguard Worker# Run deqp-vk with regres.
228*35238bceSAndroid Build Coastguard Workerdef runDeqp(deqp_path, testlist_path):
229*35238bceSAndroid Build Coastguard Worker    deqpVkParam = "--deqp-vk=" + deqp_path
230*35238bceSAndroid Build Coastguard Worker    validationLayerParam = "--validation=" + ARGS.validation
231*35238bceSAndroid Build Coastguard Worker    testListParam = "--test-list=" + testlist_path
232*35238bceSAndroid Build Coastguard Worker    run(["./run_testlist.sh", deqpVkParam, validationLayerParam, testListParam], working_dir=REGRES_DIR)
233*35238bceSAndroid Build Coastguard Worker
234*35238bceSAndroid Build Coastguard Worker# Run commands.
235*35238bceSAndroid Build Coastguard Workerdef run(command: str, working_dir: str = Path.cwd()) -> None:
236*35238bceSAndroid Build Coastguard Worker    """Run command using subprocess.run()"""
237*35238bceSAndroid Build Coastguard Worker    subprocess.run(command, cwd=working_dir, check=True)
238*35238bceSAndroid Build Coastguard Worker
239*35238bceSAndroid Build Coastguard Worker# Set VK_ICD_FILENAMES
240*35238bceSAndroid Build Coastguard Workerdef setVkIcdFilenames():
241*35238bceSAndroid Build Coastguard Worker    os.environ["VK_ICD_FILENAMES"] = str(LINUX_SWS_ICD_DIR / "vk_swiftshader_icd.json")
242*35238bceSAndroid Build Coastguard Worker    print(f"VK_ICD_FILENAMES = {os.getenv('VK_ICD_FILENAMES')}")
243*35238bceSAndroid Build Coastguard Worker
244*35238bceSAndroid Build Coastguard Worker# Choose the category/status to write results to.
245*35238bceSAndroid Build Coastguard Workerdef writeToStatus(test):
246*35238bceSAndroid Build Coastguard Worker    if test['Status'] == "PASS":
247*35238bceSAndroid Build Coastguard Worker        new_pass.append(test['Test'])
248*35238bceSAndroid Build Coastguard Worker    elif test['Status'] == "FAIL":
249*35238bceSAndroid Build Coastguard Worker        new_fail.append(test['Test'])
250*35238bceSAndroid Build Coastguard Worker    elif test['Status'] == "NOT_SUPPORTED" or test['Status'] == "UNSUPPORTED":
251*35238bceSAndroid Build Coastguard Worker        new_notsupported.append(test['Test'])
252*35238bceSAndroid Build Coastguard Worker    elif test['Status'] == "CRASH":
253*35238bceSAndroid Build Coastguard Worker        new_crash.append(test['Test'])
254*35238bceSAndroid Build Coastguard Worker    elif test['Status'] == "COMPATIBILITY_WARNING":
255*35238bceSAndroid Build Coastguard Worker        compatibility_warning.append(test['Test'])
256*35238bceSAndroid Build Coastguard Worker    elif test['Status'] == "QUALITY_WARNING":
257*35238bceSAndroid Build Coastguard Worker        quality_warning.append(test['Test'])
258*35238bceSAndroid Build Coastguard Worker    elif test['Status'] == "INTERNAL_ERROR":
259*35238bceSAndroid Build Coastguard Worker        internal_errors.append(test['Test'])
260*35238bceSAndroid Build Coastguard Worker    elif test['Status'] == "WAIVER":
261*35238bceSAndroid Build Coastguard Worker        waivers.append(test['Test'])
262*35238bceSAndroid Build Coastguard Worker    else:
263*35238bceSAndroid Build Coastguard Worker        raise RuntimeError(f"Expected PASS, FAIL, NOT_SUPPORTED, UNSUPPORTED, CRASH, COMPATIBILITY_WARNING, " +
264*35238bceSAndroid Build Coastguard Worker                           f"QUALITY_WARNING, INTERNAL_ERROR or WAIVER as status, " +
265*35238bceSAndroid Build Coastguard Worker                           f"got {test['Status']}. Is there an unhandled status case?")
266*35238bceSAndroid Build Coastguard Worker
267*35238bceSAndroid Build Coastguard Worker# Compare two result.json files for regression.
268*35238bceSAndroid Build Coastguard Workerdef compareRuns(new_result, old_result):
269*35238bceSAndroid Build Coastguard Worker    print(f"Comparing files: {old_result} and {new_result}")
270*35238bceSAndroid Build Coastguard Worker
271*35238bceSAndroid Build Coastguard Worker    r0 = Result(new_result)
272*35238bceSAndroid Build Coastguard Worker    r1 = Result(old_result)
273*35238bceSAndroid Build Coastguard Worker
274*35238bceSAndroid Build Coastguard Worker    t0 = r0.readResult()
275*35238bceSAndroid Build Coastguard Worker    t1 = r1.readResult()
276*35238bceSAndroid Build Coastguard Worker
277*35238bceSAndroid Build Coastguard Worker    done = False
278*35238bceSAndroid Build Coastguard Worker
279*35238bceSAndroid Build Coastguard Worker    while not done:
280*35238bceSAndroid Build Coastguard Worker        # Old result file has ended, continue with new.
281*35238bceSAndroid Build Coastguard Worker        if t1 == None and t0 != None:
282*35238bceSAndroid Build Coastguard Worker            advance1 = False
283*35238bceSAndroid Build Coastguard Worker            writeToStatus(t0)
284*35238bceSAndroid Build Coastguard Worker        # New result file has ended, continue with old.
285*35238bceSAndroid Build Coastguard Worker        elif t0 == None and t1 != None:
286*35238bceSAndroid Build Coastguard Worker            advance0 = False
287*35238bceSAndroid Build Coastguard Worker            has_been_removed.append(t1['Test'])
288*35238bceSAndroid Build Coastguard Worker        # Both files have ended, stop iteration.
289*35238bceSAndroid Build Coastguard Worker        elif t1 == None and t0 == None:
290*35238bceSAndroid Build Coastguard Worker            done = True
291*35238bceSAndroid Build Coastguard Worker        # By default advance both files.
292*35238bceSAndroid Build Coastguard Worker        else:
293*35238bceSAndroid Build Coastguard Worker            advance0 = True
294*35238bceSAndroid Build Coastguard Worker            advance1 = True
295*35238bceSAndroid Build Coastguard Worker
296*35238bceSAndroid Build Coastguard Worker            if t0['Test'] == t1['Test']:
297*35238bceSAndroid Build Coastguard Worker                # The normal case where both files are in sync. Just check if the status matches.
298*35238bceSAndroid Build Coastguard Worker                if t0['Status'] != t1['Status']:
299*35238bceSAndroid Build Coastguard Worker                    status_change.append(f"{t0['Test']}, new status: {t0['Status']}, old status: {t1['Status']}")
300*35238bceSAndroid Build Coastguard Worker                    print(f"Status changed: {t0['Test']} {t0['Status']} vs {t1['Status']}")
301*35238bceSAndroid Build Coastguard Worker            else:
302*35238bceSAndroid Build Coastguard Worker                # Create temporary objects for searching through the whole file.
303*35238bceSAndroid Build Coastguard Worker                tmp0 = Result(r0.filename)
304*35238bceSAndroid Build Coastguard Worker                tmp1 = Result(r1.filename)
305*35238bceSAndroid Build Coastguard Worker
306*35238bceSAndroid Build Coastguard Worker                # Search the mismatching test cases from the opposite file.
307*35238bceSAndroid Build Coastguard Worker                s0 = tmp0.searchTest(t1['Test'])
308*35238bceSAndroid Build Coastguard Worker                s1 = tmp1.searchTest(t0['Test'])
309*35238bceSAndroid Build Coastguard Worker
310*35238bceSAndroid Build Coastguard Worker                # Old test not in new results
311*35238bceSAndroid Build Coastguard Worker                if not s0:
312*35238bceSAndroid Build Coastguard Worker                    print(f"Missing old test {t1['Test']} from new file: {r0.filename}\n")
313*35238bceSAndroid Build Coastguard Worker                    has_been_removed.append(t1['Test'])
314*35238bceSAndroid Build Coastguard Worker                    # Don't advance this file since we already read a test case other than the missing one.
315*35238bceSAndroid Build Coastguard Worker                    advance0 = False
316*35238bceSAndroid Build Coastguard Worker
317*35238bceSAndroid Build Coastguard Worker                # New test not in old results
318*35238bceSAndroid Build Coastguard Worker                if not s1:
319*35238bceSAndroid Build Coastguard Worker                    print(f"Missing new test {t0['Test']} from old file: {r1.filename}\n")
320*35238bceSAndroid Build Coastguard Worker                    writeToStatus(t0)
321*35238bceSAndroid Build Coastguard Worker                    # Don't advance this file since we already read a test case other than the missing one.
322*35238bceSAndroid Build Coastguard Worker                    advance1 = False
323*35238bceSAndroid Build Coastguard Worker
324*35238bceSAndroid Build Coastguard Worker                if s0 and s1:
325*35238bceSAndroid Build Coastguard Worker                    # This should never happen because the test cases are in alphabetical order.
326*35238bceSAndroid Build Coastguard Worker                    # Print an error and bail out.
327*35238bceSAndroid Build Coastguard Worker                    raise RuntimeError(f"Tests in different locations: {t0['Test']}\n")
328*35238bceSAndroid Build Coastguard Worker
329*35238bceSAndroid Build Coastguard Worker            if not advance0 and not advance1:
330*35238bceSAndroid Build Coastguard Worker                # An exotic case where both tests are missing from the other file.
331*35238bceSAndroid Build Coastguard Worker                # Need to skip both.
332*35238bceSAndroid Build Coastguard Worker                advance0 = True
333*35238bceSAndroid Build Coastguard Worker                advance1 = True
334*35238bceSAndroid Build Coastguard Worker
335*35238bceSAndroid Build Coastguard Worker        if advance0:
336*35238bceSAndroid Build Coastguard Worker            t0 = r0.readResult()
337*35238bceSAndroid Build Coastguard Worker        if advance1:
338*35238bceSAndroid Build Coastguard Worker            t1 = r1.readResult()
339*35238bceSAndroid Build Coastguard Worker
340*35238bceSAndroid Build Coastguard Worker    result_file = str(COMP_RESULTS_DIR / "comparison_results_") + str(datetime.now().strftime('%m_%d_%Y_%H_%M_%S')) + ".txt"
341*35238bceSAndroid Build Coastguard Worker    print(f"Writing to file {result_file}")
342*35238bceSAndroid Build Coastguard Worker    COMP_RESULTS_DIR.mkdir(parents=True, exist_ok=True)
343*35238bceSAndroid Build Coastguard Worker
344*35238bceSAndroid Build Coastguard Worker    with open(result_file, "w") as log_file:
345*35238bceSAndroid Build Coastguard Worker        log_file.write("New passes:\n")
346*35238bceSAndroid Build Coastguard Worker        for line in new_pass:
347*35238bceSAndroid Build Coastguard Worker            log_file.write(line + "\n")
348*35238bceSAndroid Build Coastguard Worker        log_file.write("\n")
349*35238bceSAndroid Build Coastguard Worker
350*35238bceSAndroid Build Coastguard Worker        log_file.write("New fails:\n")
351*35238bceSAndroid Build Coastguard Worker        for line in new_fail:
352*35238bceSAndroid Build Coastguard Worker            log_file.write(line + "\n")
353*35238bceSAndroid Build Coastguard Worker        log_file.write("\n")
354*35238bceSAndroid Build Coastguard Worker
355*35238bceSAndroid Build Coastguard Worker        log_file.write("New crashes:\n")
356*35238bceSAndroid Build Coastguard Worker        for line in new_crash:
357*35238bceSAndroid Build Coastguard Worker            log_file.write(line + "\n")
358*35238bceSAndroid Build Coastguard Worker        log_file.write("\n")
359*35238bceSAndroid Build Coastguard Worker
360*35238bceSAndroid Build Coastguard Worker        log_file.write("New not_supported:\n")
361*35238bceSAndroid Build Coastguard Worker        for line in new_notsupported:
362*35238bceSAndroid Build Coastguard Worker            log_file.write(line + "\n")
363*35238bceSAndroid Build Coastguard Worker        log_file.write("\n")
364*35238bceSAndroid Build Coastguard Worker
365*35238bceSAndroid Build Coastguard Worker        log_file.write("Tests removed:\n")
366*35238bceSAndroid Build Coastguard Worker        for line in has_been_removed:
367*35238bceSAndroid Build Coastguard Worker            log_file.write(line + "\n")
368*35238bceSAndroid Build Coastguard Worker        log_file.write("\n")
369*35238bceSAndroid Build Coastguard Worker
370*35238bceSAndroid Build Coastguard Worker        log_file.write("Status changes:\n")
371*35238bceSAndroid Build Coastguard Worker        for line in status_change:
372*35238bceSAndroid Build Coastguard Worker            log_file.write(line + "\n")
373*35238bceSAndroid Build Coastguard Worker        log_file.write("\n")
374*35238bceSAndroid Build Coastguard Worker
375*35238bceSAndroid Build Coastguard Worker        log_file.write("Compatibility warnings:\n")
376*35238bceSAndroid Build Coastguard Worker        for line in compatibility_warning:
377*35238bceSAndroid Build Coastguard Worker            log_file.write(line + "\n")
378*35238bceSAndroid Build Coastguard Worker        log_file.write("\n")
379*35238bceSAndroid Build Coastguard Worker
380*35238bceSAndroid Build Coastguard Worker        log_file.write("Quality warnings:\n")
381*35238bceSAndroid Build Coastguard Worker        for line in quality_warning:
382*35238bceSAndroid Build Coastguard Worker            log_file.write(line + "\n")
383*35238bceSAndroid Build Coastguard Worker        log_file.write("\n")
384*35238bceSAndroid Build Coastguard Worker
385*35238bceSAndroid Build Coastguard Worker        log_file.write("Internal errors:\n")
386*35238bceSAndroid Build Coastguard Worker        for line in internal_errors:
387*35238bceSAndroid Build Coastguard Worker            log_file.write(line + "\n")
388*35238bceSAndroid Build Coastguard Worker        log_file.write("\n")
389*35238bceSAndroid Build Coastguard Worker
390*35238bceSAndroid Build Coastguard Worker        log_file.write("Waiver:\n")
391*35238bceSAndroid Build Coastguard Worker        for line in waivers:
392*35238bceSAndroid Build Coastguard Worker            log_file.write(line + "\n")
393*35238bceSAndroid Build Coastguard Worker
394*35238bceSAndroid Build Coastguard Worker    print(f"Comparison done. Results have been written to: {COMP_RESULTS_DIR}")
395*35238bceSAndroid Build Coastguard Worker
396*35238bceSAndroid Build Coastguard Worker# Build VK-GL-CTS
397*35238bceSAndroid Build Coastguard Workerdef buildCts():
398*35238bceSAndroid Build Coastguard Worker    VK_GL_CTS_BUILD_DIR.mkdir(parents=True, exist_ok=True)
399*35238bceSAndroid Build Coastguard Worker
400*35238bceSAndroid Build Coastguard Worker    FETCH_SOURCES = str(VK_GL_CTS_ROOT_DIR / "external" / "fetch_sources.py")
401*35238bceSAndroid Build Coastguard Worker    run([which("python3"), FETCH_SOURCES], working_dir=VK_GL_CTS_ROOT_DIR)
402*35238bceSAndroid Build Coastguard Worker
403*35238bceSAndroid Build Coastguard Worker    # Build VK-GL-CTS
404*35238bceSAndroid Build Coastguard Worker    buildType = "-DCMAKE_BUILD_TYPE=" + ARGS.vk_gl_cts_build_type
405*35238bceSAndroid Build Coastguard Worker    run([which("cmake"), "-GNinja", str(VK_GL_CTS_ROOT_DIR), buildType], working_dir=VK_GL_CTS_BUILD_DIR)
406*35238bceSAndroid Build Coastguard Worker    run([which("ninja"), "deqp-vk"], working_dir=VK_GL_CTS_BUILD_DIR)
407*35238bceSAndroid Build Coastguard Worker    print(f"vk-gl-cts built to: {VK_GL_CTS_BUILD_DIR}")
408*35238bceSAndroid Build Coastguard Worker
409*35238bceSAndroid Build Coastguard Worker# Clone and build SwiftShader and Vulkan validation layers.
410*35238bceSAndroid Build Coastguard Workerdef cloneSwsAndLayers():
411*35238bceSAndroid Build Coastguard Worker    # Clone SwiftShader or update if it already exists.
412*35238bceSAndroid Build Coastguard Worker    if not SWS_SRC_DIR.exists():
413*35238bceSAndroid Build Coastguard Worker        SWS_SRC_DIR.mkdir(parents=True, exist_ok=True)
414*35238bceSAndroid Build Coastguard Worker        run([which("git"), "clone", SWIFTSHADER_URL, SWS_SRC_DIR])
415*35238bceSAndroid Build Coastguard Worker    else:
416*35238bceSAndroid Build Coastguard Worker        run([which("git"), "pull", "origin"], working_dir=SWS_SRC_DIR)
417*35238bceSAndroid Build Coastguard Worker
418*35238bceSAndroid Build Coastguard Worker    # Build SwiftShader.
419*35238bceSAndroid Build Coastguard Worker    run([which("cmake"),
420*35238bceSAndroid Build Coastguard Worker            "-GNinja",
421*35238bceSAndroid Build Coastguard Worker            str(SWS_SRC_DIR),
422*35238bceSAndroid Build Coastguard Worker            "-DSWIFTSHADER_BUILD_EGL:BOOL=OFF",
423*35238bceSAndroid Build Coastguard Worker            "-DSWIFTSHADER_BUILD_GLESv2:BOOL=OFF",
424*35238bceSAndroid Build Coastguard Worker            "-DSWIFTSHADER_BUILD_TESTS:BOOL=OFF",
425*35238bceSAndroid Build Coastguard Worker            "-DINSTALL_GTEST=OFF",
426*35238bceSAndroid Build Coastguard Worker            "-DBUILD_TESTING:BOOL=OFF",
427*35238bceSAndroid Build Coastguard Worker            "-DENABLE_CTEST:BOOL=OFF",
428*35238bceSAndroid Build Coastguard Worker            "-DCMAKE_BUILD_TYPE=" + ARGS.sws_build_type],
429*35238bceSAndroid Build Coastguard Worker            working_dir=SWS_BUILD_DIR)
430*35238bceSAndroid Build Coastguard Worker    run([which("cmake"), "--build", ".", "--target", "vk_swiftshader"], working_dir=SWS_BUILD_DIR)
431*35238bceSAndroid Build Coastguard Worker
432*35238bceSAndroid Build Coastguard Worker    # Set Vulkan validation layers if flag is set.
433*35238bceSAndroid Build Coastguard Worker    if ARGS.validation == "true":
434*35238bceSAndroid Build Coastguard Worker        # Clone Vulkan validation layers or update if they already exist.
435*35238bceSAndroid Build Coastguard Worker        if not LAYERS_SRC_DIR.exists():
436*35238bceSAndroid Build Coastguard Worker            LAYERS_SRC_DIR.mkdir(parents=True, exist_ok=True)
437*35238bceSAndroid Build Coastguard Worker            run([which("git"), "clone", LAYERS_URL, LAYERS_SRC_DIR])
438*35238bceSAndroid Build Coastguard Worker        else:
439*35238bceSAndroid Build Coastguard Worker            run([which("git"), "pull", "origin"], working_dir=LAYERS_SRC_DIR)
440*35238bceSAndroid Build Coastguard Worker
441*35238bceSAndroid Build Coastguard Worker        # Build and set Vulkan validation layers.
442*35238bceSAndroid Build Coastguard Worker        LAYERS_BUILD_DIR.mkdir(parents=True, exist_ok=True)
443*35238bceSAndroid Build Coastguard Worker        UPDATE_DEPS = str(LAYERS_SRC_DIR / "scripts" / "update_deps.py")
444*35238bceSAndroid Build Coastguard Worker        run([which("python3"), UPDATE_DEPS], working_dir=LAYERS_BUILD_DIR)
445*35238bceSAndroid Build Coastguard Worker        run([which("cmake"),
446*35238bceSAndroid Build Coastguard Worker                "-GNinja",
447*35238bceSAndroid Build Coastguard Worker                "-C",
448*35238bceSAndroid Build Coastguard Worker                "helper.cmake",
449*35238bceSAndroid Build Coastguard Worker                LAYERS_SRC_DIR],
450*35238bceSAndroid Build Coastguard Worker                working_dir=LAYERS_BUILD_DIR)
451*35238bceSAndroid Build Coastguard Worker        run([which("cmake"), "--build", "."], working_dir=LAYERS_BUILD_DIR)
452*35238bceSAndroid Build Coastguard Worker        LAYERS_PATH = str(LAYERS_BUILD_DIR / "layers")
453*35238bceSAndroid Build Coastguard Worker        os.environ["VK_LAYER_PATH"] = LAYERS_PATH
454*35238bceSAndroid Build Coastguard Worker    print(f"Tools cloned and built in: {PARENT_DIR}")
455*35238bceSAndroid Build Coastguard Worker
456*35238bceSAndroid Build Coastguard Worker# Run cts with regres and move result files accordingly.
457*35238bceSAndroid Build Coastguard Workerdef runCts():
458*35238bceSAndroid Build Coastguard Worker    setVkIcdFilenames()
459*35238bceSAndroid Build Coastguard Worker
460*35238bceSAndroid Build Coastguard Worker    # Run cts and copy the resulting file to RESULT_DIR.
461*35238bceSAndroid Build Coastguard Worker    print("Running cts...")
462*35238bceSAndroid Build Coastguard Worker    runDeqp(str(DEQP_VK_BINARY), str(MUSTPASS_LIST))
463*35238bceSAndroid Build Coastguard Worker    RESULT_DIR.mkdir(parents=True, exist_ok=True)
464*35238bceSAndroid Build Coastguard Worker    copyfile(str(REGRES_DIR / "results.json"), str(RESULT_DIR / ARGS.result_output))
465*35238bceSAndroid Build Coastguard Worker    print("Run completed.")
466*35238bceSAndroid Build Coastguard Worker    print(f"Result file copied to: {RESULT_DIR}")
467*35238bceSAndroid Build Coastguard Worker    exit(0)
468*35238bceSAndroid Build Coastguard Worker
469*35238bceSAndroid Build Coastguard Worker# Recipe for running cts.
470*35238bceSAndroid Build Coastguard Workerif ARGS.recipe == "run-deqp":
471*35238bceSAndroid Build Coastguard Worker    cloneSwsAndLayers()
472*35238bceSAndroid Build Coastguard Worker    if ARGS.deqp_vk is None:
473*35238bceSAndroid Build Coastguard Worker        buildCts()
474*35238bceSAndroid Build Coastguard Worker    runCts()
475*35238bceSAndroid Build Coastguard Worker
476*35238bceSAndroid Build Coastguard Worker# Recipe for only comparing the already existing result files.
477*35238bceSAndroid Build Coastguard Workerif ARGS.recipe == "check-comparison":
478*35238bceSAndroid Build Coastguard Worker    if ARGS.files is None:
479*35238bceSAndroid Build Coastguard Worker        raise RuntimeError("No comparable files provided. Please provide them with flag --files. Use --help for more info.")
480*35238bceSAndroid Build Coastguard Worker    newFile, oldFile = ARGS.files
481*35238bceSAndroid Build Coastguard Worker    compareRuns(str(newFile), str(oldFile))
482