xref: /aosp_15_r20/external/mesa3d/src/freedreno/decode/scripts/analyze.lua (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1*61046927SAndroid Build Coastguard Worker-- A script that compares a set of equivalent cmdstream captures from
2*61046927SAndroid Build Coastguard Worker-- various generations, looking for equivalencies between registers.
3*61046927SAndroid Build Coastguard Worker--
4*61046927SAndroid Build Coastguard Worker-- This would be run across a group of similar tests for various
5*61046927SAndroid Build Coastguard Worker-- generations, for example:
6*61046927SAndroid Build Coastguard Worker--
7*61046927SAndroid Build Coastguard Worker--   cffdump --script scripts/analyze.lua a320/quad-flat-*.rd a420/quad-flat-*.rd
8*61046927SAndroid Build Coastguard Worker--
9*61046927SAndroid Build Coastguard Worker-- This is done by comparing unique register values.  Ie. for each
10*61046927SAndroid Build Coastguard Worker-- generation, find the set of registers that have different values
11*61046927SAndroid Build Coastguard Worker-- between equivalent draw calls.
12*61046927SAndroid Build Coastguard Worker
13*61046927SAndroid Build Coastguard Workerlocal posix = require "posix"
14*61046927SAndroid Build Coastguard Worker
15*61046927SAndroid Build Coastguard Workerio.write("Analyzing Data...\n")
16*61046927SAndroid Build Coastguard Worker
17*61046927SAndroid Build Coastguard Worker-- results - table structure:
18*61046927SAndroid Build Coastguard Worker-- * [gpuname] - gpu
19*61046927SAndroid Build Coastguard Worker--   * tests
20*61046927SAndroid Build Coastguard Worker--     * [testname] - current test
21*61046927SAndroid Build Coastguard Worker--       * draws
22*61046927SAndroid Build Coastguard Worker--         * [1..n] - the draws
23*61046927SAndroid Build Coastguard Worker--           * primtype - the primitive type
24*61046927SAndroid Build Coastguard Worker--           * regs - table of values for draw
25*61046927SAndroid Build Coastguard Worker--             * [regbase] - regval
26*61046927SAndroid Build Coastguard Worker--   * regvals - table of unique values across all draws
27*61046927SAndroid Build Coastguard Worker--     * [regbase]
28*61046927SAndroid Build Coastguard Worker--       * [regval] - list of test names
29*61046927SAndroid Build Coastguard Worker--         * [1..n] - testname "." didx
30*61046927SAndroid Build Coastguard Workerlocal results = {}
31*61046927SAndroid Build Coastguard Worker
32*61046927SAndroid Build Coastguard Workerlocal test = nil
33*61046927SAndroid Build Coastguard Workerlocal gpuname = nil
34*61046927SAndroid Build Coastguard Workerlocal testname = nil
35*61046927SAndroid Build Coastguard Worker
36*61046927SAndroid Build Coastguard Worker
37*61046927SAndroid Build Coastguard Worker-- srsly, no sparse table size() op?
38*61046927SAndroid Build Coastguard Workerfunction tblsz(tbl)
39*61046927SAndroid Build Coastguard Worker  local n = 0;
40*61046927SAndroid Build Coastguard Worker  for k,v in pairs(tbl) do
41*61046927SAndroid Build Coastguard Worker    n = n + 1
42*61046927SAndroid Build Coastguard Worker  end
43*61046927SAndroid Build Coastguard Worker  return n
44*61046927SAndroid Build Coastguard Workerend
45*61046927SAndroid Build Coastguard Worker
46*61046927SAndroid Build Coastguard Worker
47*61046927SAndroid Build Coastguard Workerfunction start_cmdstream(name)
48*61046927SAndroid Build Coastguard Worker  testname = posix.basename(name)
49*61046927SAndroid Build Coastguard Worker  gpuname = posix.basename(posix.dirname(name))
50*61046927SAndroid Build Coastguard Worker  --io.write("START: gpuname=" .. gpuname .. ", testname=" .. testname .. "\n");
51*61046927SAndroid Build Coastguard Worker  local gpu = results[gpuname]
52*61046927SAndroid Build Coastguard Worker  if gpu == nil then
53*61046927SAndroid Build Coastguard Worker    gpu = {["tests"] = {}, ["regvals"] = {}}
54*61046927SAndroid Build Coastguard Worker    results[gpuname] = gpu
55*61046927SAndroid Build Coastguard Worker  end
56*61046927SAndroid Build Coastguard Worker  test = {["draws"] = {}}
57*61046927SAndroid Build Coastguard Worker  gpu["tests"][testname] = test
58*61046927SAndroid Build Coastguard Workerend
59*61046927SAndroid Build Coastguard Worker
60*61046927SAndroid Build Coastguard Workerfunction draw(primtype, nindx)
61*61046927SAndroid Build Coastguard Worker  -- RECTLIST is only used internally.. we want to ignore it for
62*61046927SAndroid Build Coastguard Worker  -- now, although it could potentially be interesting to track
63*61046927SAndroid Build Coastguard Worker  -- these separately (separating clear/restore/resolve) just to
64*61046927SAndroid Build Coastguard Worker  -- figure out which registers are used for which..
65*61046927SAndroid Build Coastguard Worker  if primtype == "DI_PT_RECTLIST" then
66*61046927SAndroid Build Coastguard Worker    return
67*61046927SAndroid Build Coastguard Worker  end
68*61046927SAndroid Build Coastguard Worker  local regtbl = {}
69*61046927SAndroid Build Coastguard Worker  local draw = {["primtype"] = primtype, ["regs"] = regtbl}
70*61046927SAndroid Build Coastguard Worker  local didx = tblsz(test["draws"])
71*61046927SAndroid Build Coastguard Worker
72*61046927SAndroid Build Coastguard Worker  test["draws"][didx] = draw
73*61046927SAndroid Build Coastguard Worker
74*61046927SAndroid Build Coastguard Worker  -- populate current regs.  For now just consider ones that have
75*61046927SAndroid Build Coastguard Worker  -- been written.. maybe we need to make that configurable in
76*61046927SAndroid Build Coastguard Worker  -- case it filters out too many registers.
77*61046927SAndroid Build Coastguard Worker  for regbase=0,0xffff do
78*61046927SAndroid Build Coastguard Worker    if regs.written(regbase) ~= 0 then
79*61046927SAndroid Build Coastguard Worker      local regval = regs.val(regbase)
80*61046927SAndroid Build Coastguard Worker
81*61046927SAndroid Build Coastguard Worker      -- track reg vals per draw:
82*61046927SAndroid Build Coastguard Worker      regtbl[regbase] = regval
83*61046927SAndroid Build Coastguard Worker
84*61046927SAndroid Build Coastguard Worker      -- also track which reg vals appear in which tests:
85*61046927SAndroid Build Coastguard Worker      local uniq_regvals = results[gpuname]["regvals"][regbase]
86*61046927SAndroid Build Coastguard Worker      if uniq_regvals == nil then
87*61046927SAndroid Build Coastguard Worker        uniq_regvals = {}
88*61046927SAndroid Build Coastguard Worker        results[gpuname]["regvals"][regbase] = uniq_regvals;
89*61046927SAndroid Build Coastguard Worker      end
90*61046927SAndroid Build Coastguard Worker      local drawlist = uniq_regvals[regval]
91*61046927SAndroid Build Coastguard Worker      if drawlist == nil then
92*61046927SAndroid Build Coastguard Worker        drawlist = {}
93*61046927SAndroid Build Coastguard Worker        uniq_regvals[regval] = drawlist
94*61046927SAndroid Build Coastguard Worker      end
95*61046927SAndroid Build Coastguard Worker      table.insert(drawlist, testname .. "." .. didx)
96*61046927SAndroid Build Coastguard Worker    end
97*61046927SAndroid Build Coastguard Worker  end
98*61046927SAndroid Build Coastguard Worker
99*61046927SAndroid Build Coastguard Worker  -- TODO maybe we want to whitelist a few well known regs, for the
100*61046927SAndroid Build Coastguard Worker  -- convenience of the code that runs at the end to analyze the data?
101*61046927SAndroid Build Coastguard Worker  -- TODO also would be useful to somehow capture CP_SET_BIN..
102*61046927SAndroid Build Coastguard Worker
103*61046927SAndroid Build Coastguard Workerend
104*61046927SAndroid Build Coastguard Worker
105*61046927SAndroid Build Coastguard Workerfunction end_cmdstream()
106*61046927SAndroid Build Coastguard Worker  test = nil
107*61046927SAndroid Build Coastguard Worker  gpuname = nil
108*61046927SAndroid Build Coastguard Worker  testname = nil
109*61046927SAndroid Build Coastguard Workerend
110*61046927SAndroid Build Coastguard Worker
111*61046927SAndroid Build Coastguard Workerfunction print_draws(gpuname, gpu)
112*61046927SAndroid Build Coastguard Worker  io.write("  " .. gpuname .. "\n")
113*61046927SAndroid Build Coastguard Worker  for testname,test in pairs(gpu["tests"]) do
114*61046927SAndroid Build Coastguard Worker    io.write("    " .. testname .. ", draws=" .. #test["draws"] .. "\n")
115*61046927SAndroid Build Coastguard Worker    for didx,draw in pairs(test["draws"]) do
116*61046927SAndroid Build Coastguard Worker      io.write("      " .. didx .. ": " .. draw["primtype"] .. "\n")
117*61046927SAndroid Build Coastguard Worker    end
118*61046927SAndroid Build Coastguard Worker  end
119*61046927SAndroid Build Coastguard Workerend
120*61046927SAndroid Build Coastguard Worker
121*61046927SAndroid Build Coastguard Worker-- sort and concat a list of draw names to form a key which can be
122*61046927SAndroid Build Coastguard Worker-- compared to other drawlists to check for equality
123*61046927SAndroid Build Coastguard Worker-- TODO maybe we instead want a scheme that allows for some fuzzyness
124*61046927SAndroid Build Coastguard Worker-- in the matching??
125*61046927SAndroid Build Coastguard Workerfunction drawlistname(drawlist)
126*61046927SAndroid Build Coastguard Worker  local name = nil
127*61046927SAndroid Build Coastguard Worker  for idx,draw in pairs(drawlist) do
128*61046927SAndroid Build Coastguard Worker    if name == nil then
129*61046927SAndroid Build Coastguard Worker      name = draw
130*61046927SAndroid Build Coastguard Worker    else
131*61046927SAndroid Build Coastguard Worker      name = name .. ":" .. draw
132*61046927SAndroid Build Coastguard Worker    end
133*61046927SAndroid Build Coastguard Worker  end
134*61046927SAndroid Build Coastguard Worker  return name
135*61046927SAndroid Build Coastguard Workerend
136*61046927SAndroid Build Coastguard Worker
137*61046927SAndroid Build Coastguard Workerlocal rnntbl = {}
138*61046927SAndroid Build Coastguard Worker
139*61046927SAndroid Build Coastguard Workerfunction dumpmatches(name)
140*61046927SAndroid Build Coastguard Worker  for gpuname,gpu in pairs(results) do
141*61046927SAndroid Build Coastguard Worker    local r = rnntbl[gpuname]
142*61046927SAndroid Build Coastguard Worker    if r == nil then
143*61046927SAndroid Build Coastguard Worker      io.write("loading rnn database: \n" .. gpuname)
144*61046927SAndroid Build Coastguard Worker      r = rnn.init(gpuname)
145*61046927SAndroid Build Coastguard Worker      rnntbl[gpuname] = r
146*61046927SAndroid Build Coastguard Worker    end
147*61046927SAndroid Build Coastguard Worker    for regbase,regvals in pairs(gpu["regvals"]) do
148*61046927SAndroid Build Coastguard Worker      for regval,drawlist in pairs(regvals) do
149*61046927SAndroid Build Coastguard Worker        local name2 = drawlistname(drawlist)
150*61046927SAndroid Build Coastguard Worker        if name == name2 then
151*61046927SAndroid Build Coastguard Worker          io.write(string.format("  %s:%s:\t%08x  %s\n",
152*61046927SAndroid Build Coastguard Worker                                 gpuname, rnn.regname(r, regbase),
153*61046927SAndroid Build Coastguard Worker                                 regval, rnn.regval(r, regbase, regval)))
154*61046927SAndroid Build Coastguard Worker        end
155*61046927SAndroid Build Coastguard Worker      end
156*61046927SAndroid Build Coastguard Worker    end
157*61046927SAndroid Build Coastguard Worker  end
158*61046927SAndroid Build Coastguard Workerend
159*61046927SAndroid Build Coastguard Worker
160*61046927SAndroid Build Coastguard Workerfunction finish()
161*61046927SAndroid Build Coastguard Worker  -- drawlistnames that we've already dumped:
162*61046927SAndroid Build Coastguard Worker  local dumped = {}
163*61046927SAndroid Build Coastguard Worker
164*61046927SAndroid Build Coastguard Worker  for gpuname,gpu in pairs(results) do
165*61046927SAndroid Build Coastguard Worker    -- print_draws(gpuname, gpu)
166*61046927SAndroid Build Coastguard Worker    for regbase,regvals in pairs(gpu["regvals"]) do
167*61046927SAndroid Build Coastguard Worker      for regval,drawlist in pairs(regvals) do
168*61046927SAndroid Build Coastguard Worker        local name = drawlistname(drawlist)
169*61046927SAndroid Build Coastguard Worker        if dumped[name] == nil then
170*61046927SAndroid Build Coastguard Worker          io.write("\n" .. name .. ":\n")
171*61046927SAndroid Build Coastguard Worker          dumpmatches(name)
172*61046927SAndroid Build Coastguard Worker          dumped[name] = 1
173*61046927SAndroid Build Coastguard Worker        end
174*61046927SAndroid Build Coastguard Worker      end
175*61046927SAndroid Build Coastguard Worker    end
176*61046927SAndroid Build Coastguard Worker  end
177*61046927SAndroid Build Coastguard Workerend
178*61046927SAndroid Build Coastguard Worker
179