17ec681f3Smrg-- Parse logs from https://github.com/freedreno/freedreno/
27ec681f3Smrg-- test-texturator.c to generate a src/freedreno/fdl/fd5_layout_test.c
37ec681f3Smrg-- block.  We figure out the offsets from blits, but there may be some
47ec681f3Smrg-- unrelated blits.  So just save all of them until we find the
57ec681f3Smrg-- texture state.  This gives us the base address, and the miplevel #0
67ec681f3Smrg-- width/height/depth.  Then work backwards from there finding the
77ec681f3Smrg-- blits to the same dst buffer and deducing the miplevel from the
87ec681f3Smrg-- minified dimensions
97ec681f3Smrg
107ec681f3Smrglocal posix = require "posix"
117ec681f3Smrg
127ec681f3Smrgio.write("Analyzing Data...\n")
137ec681f3Smrg
147ec681f3Smrglocal r = rnn.init("a530")
157ec681f3Smrglocal found_tex = 0
167ec681f3Smrg
177ec681f3Smrglocal allblits = {}
187ec681f3Smrglocal nallblits = 0
197ec681f3Smrg
207ec681f3Smrgfunction get_first_blit(base, width, height)
217ec681f3Smrg  local first_blit = nil
227ec681f3Smrg
237ec681f3Smrg  for n = 0,nallblits-1 do
247ec681f3Smrg    local blit = allblits[n]
257ec681f3Smrg    if blit.base == base and blit.width == width and blit.height == height then
267ec681f3Smrg      if not first_blit or blit.addr < first_blit.addr then
277ec681f3Smrg        first_blit = blit
287ec681f3Smrg      end
297ec681f3Smrg    end
307ec681f3Smrg  end
317ec681f3Smrg
327ec681f3Smrg  return first_blit
337ec681f3Smrgend
347ec681f3Smrg
357ec681f3Smrgfunction minify(val, lvls)
367ec681f3Smrg  val = val >> lvls
377ec681f3Smrg  if val < 1 then
387ec681f3Smrg    return 1
397ec681f3Smrg  end
407ec681f3Smrg  return val
417ec681f3Smrgend
427ec681f3Smrg
437ec681f3Smrgfunction printf(fmt, ...)
447ec681f3Smrg  return io.write(string.format(fmt, ...))
457ec681f3Smrgend
467ec681f3Smrg
477ec681f3Smrgfunction start_cmdstream(name)
487ec681f3Smrg  io.write("Parsing " .. name .. "\n")
497ec681f3Smrg  allblits = {}
507ec681f3Smrg  nallblits = 0
517ec681f3Smrgend
527ec681f3Smrg
537ec681f3Smrg-- Record texture upload blits done through CP_EVENT_WRITE
547ec681f3Smrgfunction CP_EVENT_WRITE(pkt, size)
557ec681f3Smrg  if tostring(pkt[0].EVENT) ~= "BLIT" then
567ec681f3Smrg    return
577ec681f3Smrg  end
587ec681f3Smrg
597ec681f3Smrg  local blit = {}
607ec681f3Smrg
617ec681f3Smrg  blit.width   = r.RB_RESOLVE_CNTL_2.X + 1
627ec681f3Smrg  blit.height  = r.RB_RESOLVE_CNTL_2.Y + 1
637ec681f3Smrg  blit.pitch   = r.RB_BLIT_DST_PITCH
647ec681f3Smrg  blit.addr    = r.RB_BLIT_DST_LO | (r.RB_BLIT_DST_HI << 32)
657ec681f3Smrg  blit.base    = bos.base(blit.addr)
667ec681f3Smrg  blit.ubwc_addr = r.RB_BLIT_FLAG_DST_LO | (r.RB_BLIT_FLAG_DST_HI << 32)
677ec681f3Smrg  blit.ubwc_base = bos.base(blit.ubwc_addr)
687ec681f3Smrg  blit.ubwc_pitch = r.RB_BLIT_FLAG_DST_PITCH
697ec681f3Smrg  blit.endaddr = 0  -- filled in later
707ec681f3Smrg  printf("Found event blit: 0x%x (0x%x) %dx%d UBWC 0x%x (0x%x) tiled %s\n", blit.addr, blit.base, blit.width, blit.height, blit.ubwc_addr, blit.ubwc_base, r.RB_RESOLVE_CNTL_3.TILED)
717ec681f3Smrg
727ec681f3Smrg  allblits[nallblits] = blit
737ec681f3Smrg  nallblits = nallblits + 1
747ec681f3Smrgend
757ec681f3Smrg
767ec681f3Smrgfunction CP_BLIT(pkt, size)
777ec681f3Smrg  -- Just in case, filter out anything that isn't starting
787ec681f3Smrg  -- at 0,0
797ec681f3Smrg  if pkt[1].SRC_X1 ~= 0 or pkt[1].SRC_Y1 ~= 0 then
807ec681f3Smrg    return
817ec681f3Smrg  end
827ec681f3Smrg
837ec681f3Smrg  local blit = {}
847ec681f3Smrg
857ec681f3Smrg  blit.width   = pkt[2].SRC_X2 + 1
867ec681f3Smrg  blit.height  = pkt[2].SRC_Y2 + 1
877ec681f3Smrg  blit.pitch   = r.RB_2D_DST_SIZE.PITCH
887ec681f3Smrg  blit.addr    = r.RB_2D_DST_LO | (r.RB_2D_DST_HI << 32)
897ec681f3Smrg  blit.base    = bos.base(blit.addr)
907ec681f3Smrg  blit.ubwc_addr = r.RB_2D_DST_FLAGS_LO | (r.RB_2D_DST_FLAGS_HI << 32)
917ec681f3Smrg  blit.ubwc_base = bos.base(blit.ubwc_addr)
927ec681f3Smrg  blit.ubwc_pitch = r.RB_2D_DST_FLAGS_PITCH
937ec681f3Smrg  blit.endaddr = 0  -- filled in later
947ec681f3Smrg  printf("Found cp blit: 0x%x (0x%x) %dx%d UBWC 0x%x (0x%x) %s\n", blit.addr, blit.base, blit.width, blit.height, blit.ubwc_addr, blit.ubwc_base, r.RB_2D_DST_INFO.TILE_MODE)
957ec681f3Smrg
967ec681f3Smrg  allblits[nallblits] = blit
977ec681f3Smrg  nallblits = nallblits + 1
987ec681f3Smrgend
997ec681f3Smrg
1007ec681f3Smrgfunction A5XX_TEX_CONST(pkt, size)
1017ec681f3Smrg  -- ignore any texture state w/ DEPTH=1, these aren't the 3d tex state we
1027ec681f3Smrg  -- are looking for
1037ec681f3Smrg
1047ec681f3Smrg  local base = pkt[4].BASE_LO | (pkt[5].BASE_HI << 32)
1057ec681f3Smrg  -- UBWC base on a5xx seems to be at the start of each miplevel, followed by pixels
1067ec681f3Smrg  -- somewhere past that.
1077ec681f3Smrg  local ubwc_base = base
1087ec681f3Smrg  local width0  = pkt[1].WIDTH
1097ec681f3Smrg  local height0 = pkt[1].HEIGHT
1107ec681f3Smrg  local depth0  = pkt[5].DEPTH
1117ec681f3Smrg
1127ec681f3Smrg  if (found_tex ~= 0) then
1137ec681f3Smrg    return
1147ec681f3Smrg  end
1157ec681f3Smrg  found_tex = 1
1167ec681f3Smrg
1177ec681f3Smrg  printf("Found texture state:\n  %ux%ux%u (%s, %s, UBWC=%s)\n",
1187ec681f3Smrg         width0, height0, depth0, pkt[0].FMT, pkt[0].TILE_MODE, tostring(pkt[3].FLAG))
1197ec681f3Smrg
1207ec681f3Smrg  -- Note that in some case the texture has some extra page or so
1217ec681f3Smrg  -- at the beginning:
1227ec681f3Smrg  local basebase = bos.base(base)
1237ec681f3Smrg  printf("base: 0x%x (0x%x)\n", base, basebase)
1247ec681f3Smrg  printf("ubwcbase: 0x%x (0x%x)\n", ubwc_base, bos.base(ubwc_base))
1257ec681f3Smrg
1267ec681f3Smrg  -- see if we can find the associated blits..  The blob always seems to
1277ec681f3Smrg  -- start from the lower (larger) mipmap levels and layers, so we don't
1287ec681f3Smrg  -- need to sort by dst address.  Also, while we are at it, fill in the
1297ec681f3Smrg  -- end-addr (at least for everything but the last blit)
1307ec681f3Smrg  local blits = {}
1317ec681f3Smrg  local nblits = 0
1327ec681f3Smrg  local lastblit = nil
1337ec681f3Smrg  for n = 0,nallblits-1 do
1347ec681f3Smrg    local blit = allblits[n]
1357ec681f3Smrg    --printf("blit addr: 0x%x (0x%x)\n", blit.addr, blit.base)
1367ec681f3Smrg    if blit.base == basebase and blit.addr >= base then
1377ec681f3Smrg      blits[nblits] = blit
1387ec681f3Smrg      nblits = nblits + 1
1397ec681f3Smrg      if lastblit then
1407ec681f3Smrg        lastblit.endaddr = blit.addr
1417ec681f3Smrg      end
1427ec681f3Smrg      lastblit = blit
1437ec681f3Smrg    end
1447ec681f3Smrg  end
1457ec681f3Smrg
1467ec681f3Smrg  printf("	{\n")
1477ec681f3Smrg  printf("		.format = %s,\n", pkt[0].FMT)
1487ec681f3Smrg  if (tostring(pkt[2].TYPE) == "A5XX_TEX_3D") then
1497ec681f3Smrg    printf("		.is_3d = true,\n")
1507ec681f3Smrg  end
1517ec681f3Smrg
1527ec681f3Smrg  printf("		.layout = {\n")
1537ec681f3Smrg  printf("			.tile_mode = %s,\n", pkt[0].TILE_MODE)
1547ec681f3Smrg  printf("			.ubwc = %s,\n", tostring(pkt[3].FLAG))
1557ec681f3Smrg
1567ec681f3Smrg  if (tostring(pkt[2].TYPE) == "A5XX_TEX_3D") then
1577ec681f3Smrg    printf("			.width0 = %d, .height0 = %d, .depth0 = %d,\n", width0, height0, depth0)
1587ec681f3Smrg  else
1597ec681f3Smrg    printf("			.width0 = %d, .height0 = %d,\n", width0, height0)
1607ec681f3Smrg  end
1617ec681f3Smrg
1627ec681f3Smrg  printf("			.slices = {\n")
1637ec681f3Smrg  local w = 0
1647ec681f3Smrg  local h = 0
1657ec681f3Smrg  local level = 0
1667ec681f3Smrg  repeat
1677ec681f3Smrg    local w = minify(width0, level)
1687ec681f3Smrg    local h = minify(height0, level)
1697ec681f3Smrg    local blit = get_first_blit(basebase, w, h)
1707ec681f3Smrg    if blit then
1717ec681f3Smrg      printf("				{ .offset = %d, .pitch = %u },\n",
1727ec681f3Smrg          blit.addr - base,
1737ec681f3Smrg          blit.pitch);
1747ec681f3Smrg    end
1757ec681f3Smrg    level = level + 1
1767ec681f3Smrg  until w == 1 and h == 1
1777ec681f3Smrg  printf("			},\n")
1787ec681f3Smrg
1797ec681f3Smrg  if pkt[3].FLAG then
1807ec681f3Smrg    printf("			.ubwc_slices = {\n")
1817ec681f3Smrg    level = 0
1827ec681f3Smrg    repeat
1837ec681f3Smrg      local w = minify(width0, level)
1847ec681f3Smrg      local h = minify(height0, level)
1857ec681f3Smrg      local blit = get_first_blit(basebase, w, h)
1867ec681f3Smrg      if blit then
1877ec681f3Smrg        printf("				{ .offset = %d, .pitch = %u },\n",
1887ec681f3Smrg            blit.ubwc_addr - ubwc_base,
1897ec681f3Smrg            blit.ubwc_pitch);
1907ec681f3Smrg      end
1917ec681f3Smrg      level = level + 1
1927ec681f3Smrg    until w == 1 and h == 1
1937ec681f3Smrg    printf("			},\n")
1947ec681f3Smrg  end
1957ec681f3Smrg
1967ec681f3Smrg  printf("		},\n")
1977ec681f3Smrg  printf("	},\n")
1987ec681f3Smrg  printf("\n\n")
1997ec681f3Smrgend
2007ec681f3Smrg
201