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