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