#!/usr/bin/python ''' Parse separate command buffer (outside of fdr), used for processing debug output. ''' # Copyright (c) 2012-2013 Wladimir J. van der Laan # # Permission is hereby granted, free of charge, to any person obtaining a # copy of this software and associated documentation files (the "Software"), # to deal in the Software without restriction, including without limitation # the rights to use, copy, modify, merge, publish, distribute, sub license, # and/or sell copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice (including the # next paragraph) shall be included in all copies or substantial portions # of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL # THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER # DEALINGS IN THE SOFTWARE. from __future__ import print_function, division, unicode_literals import argparse import os, sys, struct import json from collections import defaultdict from binascii import b2a_hex # Parse rules-ng-ng format for state space from etnaviv.util import rnndb_path from etnaviv.parse_rng import parse_rng_file, format_path, BitSet, Domain from etnaviv.dump_cmdstream_util import int_as_float, fixp_as_float from etnaviv.parse_command_buffer import parse_command_buffer DEBUG = False COMPS = 'xyzw' def format_state(pos, value, fixp, state_map): try: path = state_map.lookup_address(pos) path_str = format_path(path) #+ ('(0x%05X)' % pos) except KeyError: path = None path_str = '0x%05X' % pos desc = ' ' + path_str if fixp: desc += ' = %f' % fixp_as_float(value) else: # For uniforms, show float value if (pos >= 0x05000 and pos < 0x06000) or (pos >= 0x07000 and pos < 0x08000): num = pos & 0xFFF spec = 'u%i.%s' % (num//16, COMPS[(num//4)%4]) desc += ' := %f (%s)' % (int_as_float(value), spec) elif path is not None: register = path[-1][0] desc += ' := ' desc += register.describe(value) return desc def dump_command_buffer(f, buf, depth, state_map): ''' Dump Vivante command buffer contents in human-readable format. ''' indent = ' ' * len(depth) f.write('{\n') size = len(buf) states = [] # list of (ptr, state_addr) tuples ptr = 0 for rec in parse_command_buffer(buf): hide = False if rec.op == 1 and rec.payload_ofs == -1: if options.hide_load_state: hide = True if rec.state_info is not None: states.append((rec.ptr, rec.state_info.pos, rec.state_info.format, rec.value)) desc = format_state(rec.state_info.pos, rec.value, rec.state_info.format, state_map) else: desc = rec.desc if not hide: f.write(indent + ' 0x%08x' % rec.value) if ptr != (size-1): f.write(", /* %s */\n" % rec.desc) else: f.write(" /* %s */\n" % rec.desc) ptr += 1 f.write(indent + '}') def parse_arguments(): parser = argparse.ArgumentParser(description='Parse execution data log stream.') parser.add_argument('input_file', metavar='INFILE', type=str, help='FDR file') parser.add_argument('--rules-file', metavar='RULESFILE', type=str, help='State map definition file (rules-ng-ng)', default=rnndb_path('state.xml')) parser.add_argument('-l', '--hide-load-state', dest='hide_load_state', default=False, action='store_const', const=True, help='Hide "LOAD_STATE" entries, this can make command stream a bit easier to read') return parser.parse_args() shader_num = 0 def main(): args = parse_arguments() state_xml = parse_rng_file(args.rules_file) state_map = state_xml.lookup_domain('VIVS') global options options = args import re with open(args.input_file,'r') as f: # parse ascii values = [] for line in f: value = line.strip() if value.startswith(':'): value = int(value[1:9], 16) values.append(value) dump_command_buffer(sys.stdout, values, [], state_map) sys.stdout.write('\n') if __name__ == '__main__': main()