Path: blob/21.2-virgl/src/freedreno/decode/scripts/parse-submits.lua
4573 views
-- Parse cmdstream dump and analyse blits and batches12--local posix = require "posix"34function printf(fmt, ...)5return io.write(string.format(fmt, ...))6end78function dbg(fmt, ...)9--printf(fmt, ...)10end1112printf("Analyzing Data...\n")1314local r = rnn.init("a630")1516-- Each submit, all draws will target the same N MRTs:17local mrts = {}18local allmrts = {} -- includes historical render targets19function push_mrt(fmt, w, h, samples, base, flag, gmem)20dbg("MRT: %s %ux%u 0x%x\n", fmt, w, h, base)2122local mrt = {}23mrt.format = fmt24mrt.w = w25mrt.h = h26mrt.samples = samples27mrt.base = base28mrt.flag = flag29mrt.gmem = gmem3031mrts[base] = mrt32allmrts[base] = mrt33end3435-- And each each draw will read from M sources/textures:36local sources = {}37function push_source(fmt, w, h, samples, base, flag)38dbg("SRC: %s %ux%u 0x%x\n", fmt, w, h, base)3940local source = {}41source.format = fmt42source.w = w43source.h = h44source.samples = samples45source.base = base46source.flag = flag4748sources[base] = source49end5051local binw52local binh53local nbins54local blits = 055local draws = 056local drawmode57local cleared58local restored59local resolved60local nullbatch61local depthtest62local depthwrite63local stenciltest64local stencilwrite6566function start_cmdstream(name)67printf("Parsing %s\n", name)68end6970function reset()71dbg("reset\n")72mrts = {}73sources = {}74draws = 075blits = 076cleared = {}77restored = {}78resolved = {}79depthtest = false80depthwrite = false81stenciltest = false82stencilwrite = false83drawmode = Nil84end8586function start_submit()87dbg("start_submit\n")88reset()89nullbatch = true90end9192function finish()93dbg("finish\n")9495printf("\n")9697-- TODO we get false-positives for 'NULL BATCH!' because we don't have98-- a really good way to differentiate between submits and cmds. Ie.99-- with growable cmdstream, and a large # of tiles, IB1 can get split100-- across multiple buffers. Since we ignore GMEM draws for window-101-- offset != 0,0, the later cmds will appear as null batches102if draws == 0 and blits == 0 then103if nullbatch then104printf("NULL BATCH!\n");105end106return107end108109if draws > 0 then110printf("Batch:\n")111printf("-------\n")112printf(" # of draws: %u\n", draws)113printf(" mode: %s\n", drawmode)114if drawmode == "RM6_GMEM" then115printf(" bin size: %ux%u (%u bins)\n", binw, binh, nbins)116end117if depthtest or depthwrite then118printf(" ")119if depthtest then120printf("DEPTHTEST ")121end122if depthwrite then123printf("DEPTHWRITE")124end125printf("\n")126end127if stenciltest or stencilwrite then128printf(" ")129if stenciltest then130printf("STENCILTEST ")131end132if stencilwrite then133printf("STENCILWRITE")134end135printf("\n")136end137else138printf("Blit:\n")139printf("-----\n")140end141142for base,mrt in pairs(mrts) do143printf(" MRT[0x%x:0x%x]:\t%ux%u\t\t%s (%s)", base, mrt.flag, mrt.w, mrt.h, mrt.format, mrt.samples)144if drawmode == "RM6_GMEM" then145if cleared[mrt.gmem] then146printf("\tCLEARED")147end148if restored[mrt.gmem] then149printf("\tRESTORED")150end151if resolved[mrt.gmem] then152printf("\tRESOLVED")153end154else155if cleared[mrt.base] then156printf("\tCLEARED")157end158end159printf("\n")160end161162function print_source(source)163printf(" SRC[0x%x:0x%x]:\t%ux%u\t\t%s (%s)\n", source.base, source.flag, source.w, source.h, source.format, source.samples)164end165166for base,source in pairs(sources) do167-- only show sources that have been previously rendered to, other168-- textures are less interesting. Possibly this should be an169-- option somehow170if draws < 10 then171print_source(source)172elseif allmrts[base] or draws == 0 then173print_source(source)174elseif source.flag and allmrts[source.flag] then175print_source(source)176end177end178reset()179end180181function end_submit()182dbg("end_submit\n")183finish()184end185186-- Track the current mode:187local mode = ""188function CP_SET_MARKER(pkt, size)189mode = pkt[0].MARKER190dbg("mode: %s\n", mode)191end192193function CP_EVENT_WRITE(pkt, size)194if tostring(pkt[0].EVENT) ~= "BLIT" then195return196end197nullbatch = false198local m = tostring(mode)199if m == "RM6_GMEM" then200-- either clear or restore:201if r.RB_BLIT_INFO.CLEAR_MASK == 0 then202restored[r.RB_BLIT_BASE_GMEM] = 1203else204cleared[r.RB_BLIT_BASE_GMEM] = 1205end206-- push_mrt() because we could have GMEM207-- passes with only a clear and no draws:208local flag = 0209local sysmem = 0;210-- try to match up the GMEM addr with the MRT/DEPTH state,211-- to avoid relying on RB_BLIT_DST also getting written:212for n = 0,r.RB_FS_OUTPUT_CNTL1.MRT-1 do213if r.RB_MRT[n].BASE_GMEM == r.RB_BLIT_BASE_GMEM then214sysmem = r.RB_MRT[n].BASE215flag = r.RB_MRT_FLAG_BUFFER[n].ADDR216break217end218end219if sysmem == 0 and r.RB_BLIT_BASE_GMEM == r.RB_DEPTH_BUFFER_BASE_GMEM then220sysmem = r.RB_DEPTH_BUFFER_BASE221flag = r.RB_DEPTH_FLAG_BUFFER_BASE222223end224--NOTE this can get confused by previous blits:225--if sysmem == 0 then226-- -- fallback:227-- sysmem = r.RB_BLIT_DST228-- flag = r.RB_BLIT_FLAG_DST229--end230if not r.RB_BLIT_DST_INFO.FLAGS then231flag = 0232end233-- TODO maybe just emit RB_BLIT_DST/HI for clears.. otherwise234-- we get confused by stale values in registers.. not sure235-- if this is a problem w/ blob236push_mrt(r.RB_BLIT_DST_INFO.COLOR_FORMAT,237r.RB_BLIT_SCISSOR_BR.X + 1,238r.RB_BLIT_SCISSOR_BR.Y + 1,239r.RB_BLIT_DST_INFO.SAMPLES,240sysmem,241flag,242r.RB_BLIT_BASE_GMEM)243elseif m == "RM6_RESOLVE" then244resolved[r.RB_BLIT_BASE_GMEM] = 1245else246printf("I am confused!!!\n")247end248end249250function A6XX_TEX_CONST(pkt, size)251push_source(pkt[0].FMT,252pkt[1].WIDTH, pkt[1].HEIGHT,253pkt[0].SAMPLES,254pkt[4].BASE_LO | (pkt[5].BASE_HI << 32),255pkt[7].FLAG_LO | (pkt[8].FLAG_HI << 32))256end257258function handle_blit()259-- blob sometimes uses CP_BLIT for resolves, so filter those out:260-- TODO it would be nice to not hard-code GMEM addr:261-- TODO I guess the src can be an offset from GMEM addr..262if r.SP_PS_2D_SRC == 0x100000 and not r.RB_2D_BLIT_CNTL.SOLID_COLOR then263resolved[0] = 1264return265end266if draws > 0 then267finish()268end269reset()270drawmode = "BLIT"271-- This kinda assumes that we are doing full img blits, which is maybe272-- Not completely legit. We could perhaps instead just track pitch and273-- size/pitch?? Or maybe the size doesn't matter much274push_mrt(r.RB_2D_DST_INFO.COLOR_FORMAT,275r.GRAS_2D_DST_BR.X + 1,276r.GRAS_2D_DST_BR.Y + 1,277"MSAA_ONE",278r.RB_2D_DST,279r.RB_2D_DST_FLAGS,280-1)281if r.RB_2D_BLIT_CNTL.SOLID_COLOR then282dbg("CLEAR=%x\n", r.RB_2D_DST)283cleared[r.RB_2D_DST] = 1284else285push_source(r.SP_2D_SRC_FORMAT.COLOR_FORMAT,286r.GRAS_2D_SRC_BR_X.X + 1,287r.GRAS_2D_SRC_BR_Y.Y + 1,288"MSAA_ONE",289r.SP_PS_2D_SRC,290r.SP_PS_2D_SRC_FLAGS)291end292blits = blits + 1293finish()294end295296function valid_transition(curmode, newmode)297if curmode == "RM6_BINNING" and newmode == "RM6_GMEM" then298return true299end300if curmode == "RM6_GMEM" and newmode == "RM6_RESOLVE" then301return true302end303return false304end305306function draw(primtype, nindx)307dbg("draw: %s (%s)\n", primtype, mode)308nullbatch = false309if primtype == "BLIT_OP_SCALE" then310handle_blit()311return312elseif primtype == "EVENT:BLIT" then313return314end315316local m = tostring(mode)317318-- detect changes in drawmode which indicate a different319-- pass.. BINNING->GMEM means same pass, but other320-- transitions mean different pass:321if drawmode and m ~= drawmode then322dbg("%s -> %s transition\n", drawmode, m)323if not valid_transition(drawmode, m) then324dbg("invalid transition, new render pass!\n")325finish()326reset()327end328end329330if m ~= "RM6_GMEM" and m ~= "RM6_BYPASS" then331if m == "RM6_BINNING" then332drawmode = m333return334end335if m == "RM6_RESOLVE" and primtype == "EVENT:BLIT" then336return337end338printf("unknown MODE %s for primtype %s\n", m, primtype)339return340end341342-- Only count the first tile for GMEM mode to avoid counting343-- each draw for each tile344if m == "RM6_GMEM" then345if r.RB_WINDOW_OFFSET.X ~= 0 or r.RB_WINDOW_OFFSET.Y ~= 0 then346return347end348end349350drawmode = m351local render_components = {}352render_components[0] = r.RB_RENDER_COMPONENTS.RT0;353render_components[1] = r.RB_RENDER_COMPONENTS.RT1;354render_components[2] = r.RB_RENDER_COMPONENTS.RT2;355render_components[3] = r.RB_RENDER_COMPONENTS.RT3;356render_components[4] = r.RB_RENDER_COMPONENTS.RT4;357render_components[5] = r.RB_RENDER_COMPONENTS.RT5;358render_components[6] = r.RB_RENDER_COMPONENTS.RT6;359render_components[7] = r.RB_RENDER_COMPONENTS.RT7;360for n = 0,r.RB_FS_OUTPUT_CNTL1.MRT-1 do361if render_components[n] ~= 0 then362push_mrt(r.RB_MRT[n].BUF_INFO.COLOR_FORMAT,363r.GRAS_SC_SCREEN_SCISSOR[0].BR.X + 1,364r.GRAS_SC_SCREEN_SCISSOR[0].BR.Y + 1,365r.RB_MSAA_CNTL.SAMPLES,366r.RB_MRT[n].BASE,367r.RB_MRT_FLAG_BUFFER[n].ADDR,368r.RB_MRT[n].BASE_GMEM)369end370end371372local depthbase = r.RB_DEPTH_BUFFER_BASE373374if depthbase ~= 0 then375push_mrt(r.RB_DEPTH_BUFFER_INFO.DEPTH_FORMAT,376r.GRAS_SC_SCREEN_SCISSOR[0].BR.X + 1,377r.GRAS_SC_SCREEN_SCISSOR[0].BR.Y + 1,378r.RB_MSAA_CNTL.SAMPLES,379depthbase,380r.RB_DEPTH_FLAG_BUFFER_BASE,381r.RB_DEPTH_BUFFER_BASE_GMEM)382end383384if r.RB_DEPTH_CNTL.Z_WRITE_ENABLE then385depthwrite = true386end387388if r.RB_DEPTH_CNTL.Z_ENABLE then389depthtest = true390end391392-- clearly 0 != false.. :-/393if r.RB_STENCILWRMASK.WRMASK ~= 0 then394stencilwrite = true395end396397if r.RB_STENCIL_CONTROL.STENCIL_ENABLE then398stenciltest = true399end400401-- TODO should also check for stencil buffer for z32+s8 case402403if m == "RM6_GMEM" then404binw = r.VSC_BIN_SIZE.WIDTH405binh = r.VSC_BIN_SIZE.HEIGHT406nbins = r.VSC_BIN_COUNT.NX * r.VSC_BIN_COUNT.NY407end408409draws = draws + 1410end411412413414