mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-20 04:48:07 +02:00
Sometimes you fumble an answer, and would like to not restart from the beginning (or just want to see the behavior of the script late in the run if you're debugging it). Pass in the last bad range, and you can keep going. Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/38760>
105 lines
3.3 KiB
Python
Executable file
105 lines
3.3 KiB
Python
Executable file
#!/usr/bin/env python3
|
|
|
|
import argparse
|
|
import subprocess
|
|
import os
|
|
import re
|
|
|
|
|
|
def run(args, lo, hi):
|
|
print(f'NIR_SHADER_BISECT_LO: {lo}')
|
|
print(f'NIR_SHADER_BISECT_HI: {hi}')
|
|
|
|
env = os.environ.copy()
|
|
env['MESA_SHADER_CACHE_DISABLE'] = '1'
|
|
env['NIR_SHADER_BISECT_LO'] = lo
|
|
env['NIR_SHADER_BISECT_HI'] = hi
|
|
env.pop('MESA_LOG_FILE', None)
|
|
|
|
cmd = [args.cmd] + args.cmd_args
|
|
if args.debug:
|
|
print(f"running: {cmd}")
|
|
result = subprocess.run(cmd, env=env,
|
|
text=True, capture_output=True)
|
|
if args.debug:
|
|
print(f"Result: {result.returncode}")
|
|
print("stdout:")
|
|
print(result.stdout)
|
|
print("stderr:")
|
|
print(result.stderr)
|
|
|
|
shaders = set(re.findall(
|
|
"NIR bisect selected source_blake3: (.*) \((.*)\)", result.stderr))
|
|
num = len(shaders)
|
|
print(f'Shaders matched: {num}')
|
|
if num <= 5:
|
|
for blake3, id in sorted(shaders):
|
|
print(f' {blake3}')
|
|
return shaders
|
|
|
|
|
|
def was_good():
|
|
while True:
|
|
response = input('Was the previous run [g]ood or [b]ad? ')
|
|
|
|
if response in ('g', 'b'):
|
|
return response == 'g'
|
|
|
|
|
|
def bisect(args):
|
|
lo = f'{args.lo:064x}'
|
|
hi = f'{args.hi:064x}'
|
|
|
|
# Do an initial run to sanity check that the user has actually made
|
|
# nir_shader_bisect_select() select some broken behavior.
|
|
bad = run(args, lo, hi)
|
|
if was_good():
|
|
print("Entire hash range produced a good result -- did you make nir_shader_bisect_select() select the behavior you want?")
|
|
exit(1)
|
|
|
|
if len(bad) == 0:
|
|
print("No bad shaders detected -- did you rebuild after adding nir_shader_bisect_select()?")
|
|
exit(1)
|
|
|
|
while True:
|
|
if len(bad) == 1:
|
|
for shader in bad:
|
|
print(f"Bisected to source_blake3 {shader}")
|
|
print(
|
|
f"You can now replace nir_shader_bisect_select() with _mesa_printed_blake3_equal(s->info.source_blake3, (uint32_t[]){shader[0]})")
|
|
exit(0)
|
|
else:
|
|
num = len(bad)
|
|
print(f"Shaders remaining to bisect: {num}")
|
|
if num <= 5:
|
|
for shader in sorted(bad):
|
|
print(f' {shader}')
|
|
|
|
# Find the middle shader remaining in the set of shaders from the last
|
|
# bad run, and check if the bottom half of set of possibly-bad shaders
|
|
# (up to and including it) is bad.
|
|
ids = sorted([id for blake3, id in bad])
|
|
lo = ids[0]
|
|
split = ids[(len(ids) - 1) // 2]
|
|
cur = run(args, lo, split)
|
|
|
|
if was_good():
|
|
bad = bad.difference(cur)
|
|
else:
|
|
bad = cur
|
|
|
|
|
|
if __name__ == '__main__':
|
|
parser = argparse.ArgumentParser()
|
|
|
|
parser.add_argument('-d', '--debug', action='store_true')
|
|
parser.add_argument('--lo', type=lambda x: int(x, base=16),
|
|
default=0,
|
|
help="NIR_SHADER_BISECT_LO from a bad range, to continue a cancelled run")
|
|
parser.add_argument('--hi', type=lambda x: int(x, base=16),
|
|
default=(1 << (8 * 32)) - 1,
|
|
help="NIR_SHADER_BISECT_HI from a bad range, to continue a cancelled run")
|
|
parser.add_argument('cmd')
|
|
parser.add_argument('cmd_args', nargs=argparse.REMAINDER)
|
|
args = parser.parse_args()
|
|
bisect(args)
|