1bf215546Sopenharmony_ci-- Parse logs from https://github.com/freedreno/freedreno/
2bf215546Sopenharmony_ci-- test-texturator.c to generate a src/freedreno/fdl/fd5_layout_test.c
3bf215546Sopenharmony_ci-- block.  We figure out the offsets from blits, but there may be some
4bf215546Sopenharmony_ci-- unrelated blits.  So just save all of them until we find the
5bf215546Sopenharmony_ci-- texture state.  This gives us the base address, and the miplevel #0
6bf215546Sopenharmony_ci-- width/height/depth.  Then work backwards from there finding the
7bf215546Sopenharmony_ci-- blits to the same dst buffer and deducing the miplevel from the
8bf215546Sopenharmony_ci-- minified dimensions
9bf215546Sopenharmony_ci
10bf215546Sopenharmony_cilocal posix = require "posix"
11bf215546Sopenharmony_ci
12bf215546Sopenharmony_ciio.write("Analyzing Data...\n")
13bf215546Sopenharmony_ci
14bf215546Sopenharmony_cilocal r = rnn.init("a530")
15bf215546Sopenharmony_cilocal found_tex = 0
16bf215546Sopenharmony_ci
17bf215546Sopenharmony_cilocal allblits = {}
18bf215546Sopenharmony_cilocal nallblits = 0
19bf215546Sopenharmony_ci
20bf215546Sopenharmony_cifunction get_first_blit(base, width, height)
21bf215546Sopenharmony_ci  local first_blit = nil
22bf215546Sopenharmony_ci
23bf215546Sopenharmony_ci  for n = 0,nallblits-1 do
24bf215546Sopenharmony_ci    local blit = allblits[n]
25bf215546Sopenharmony_ci    if blit.base == base and blit.width == width and blit.height == height then
26bf215546Sopenharmony_ci      if not first_blit or blit.addr < first_blit.addr then
27bf215546Sopenharmony_ci        first_blit = blit
28bf215546Sopenharmony_ci      end
29bf215546Sopenharmony_ci    end
30bf215546Sopenharmony_ci  end
31bf215546Sopenharmony_ci
32bf215546Sopenharmony_ci  return first_blit
33bf215546Sopenharmony_ciend
34bf215546Sopenharmony_ci
35bf215546Sopenharmony_cifunction minify(val, lvls)
36bf215546Sopenharmony_ci  val = val >> lvls
37bf215546Sopenharmony_ci  if val < 1 then
38bf215546Sopenharmony_ci    return 1
39bf215546Sopenharmony_ci  end
40bf215546Sopenharmony_ci  return val
41bf215546Sopenharmony_ciend
42bf215546Sopenharmony_ci
43bf215546Sopenharmony_cifunction printf(fmt, ...)
44bf215546Sopenharmony_ci  return io.write(string.format(fmt, ...))
45bf215546Sopenharmony_ciend
46bf215546Sopenharmony_ci
47bf215546Sopenharmony_cifunction start_cmdstream(name)
48bf215546Sopenharmony_ci  io.write("Parsing " .. name .. "\n")
49bf215546Sopenharmony_ci  allblits = {}
50bf215546Sopenharmony_ci  nallblits = 0
51bf215546Sopenharmony_ciend
52bf215546Sopenharmony_ci
53bf215546Sopenharmony_ci-- Record texture upload blits done through CP_EVENT_WRITE
54bf215546Sopenharmony_cifunction CP_EVENT_WRITE(pkt, size)
55bf215546Sopenharmony_ci  if tostring(pkt[0].EVENT) ~= "BLIT" then
56bf215546Sopenharmony_ci    return
57bf215546Sopenharmony_ci  end
58bf215546Sopenharmony_ci
59bf215546Sopenharmony_ci  local blit = {}
60bf215546Sopenharmony_ci
61bf215546Sopenharmony_ci  blit.width   = r.RB_RESOLVE_CNTL_2.X + 1
62bf215546Sopenharmony_ci  blit.height  = r.RB_RESOLVE_CNTL_2.Y + 1
63bf215546Sopenharmony_ci  blit.pitch   = r.RB_BLIT_DST_PITCH
64bf215546Sopenharmony_ci  blit.addr    = r.RB_BLIT_DST_LO | (r.RB_BLIT_DST_HI << 32)
65bf215546Sopenharmony_ci  blit.base    = bos.base(blit.addr)
66bf215546Sopenharmony_ci  blit.ubwc_addr = r.RB_BLIT_FLAG_DST_LO | (r.RB_BLIT_FLAG_DST_HI << 32)
67bf215546Sopenharmony_ci  blit.ubwc_base = bos.base(blit.ubwc_addr)
68bf215546Sopenharmony_ci  blit.ubwc_pitch = r.RB_BLIT_FLAG_DST_PITCH
69bf215546Sopenharmony_ci  blit.endaddr = 0  -- filled in later
70bf215546Sopenharmony_ci  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)
71bf215546Sopenharmony_ci
72bf215546Sopenharmony_ci  allblits[nallblits] = blit
73bf215546Sopenharmony_ci  nallblits = nallblits + 1
74bf215546Sopenharmony_ciend
75bf215546Sopenharmony_ci
76bf215546Sopenharmony_cifunction CP_BLIT(pkt, size)
77bf215546Sopenharmony_ci  -- Just in case, filter out anything that isn't starting
78bf215546Sopenharmony_ci  -- at 0,0
79bf215546Sopenharmony_ci  if pkt[1].SRC_X1 ~= 0 or pkt[1].SRC_Y1 ~= 0 then
80bf215546Sopenharmony_ci    return
81bf215546Sopenharmony_ci  end
82bf215546Sopenharmony_ci
83bf215546Sopenharmony_ci  local blit = {}
84bf215546Sopenharmony_ci
85bf215546Sopenharmony_ci  blit.width   = pkt[2].SRC_X2 + 1
86bf215546Sopenharmony_ci  blit.height  = pkt[2].SRC_Y2 + 1
87bf215546Sopenharmony_ci  blit.pitch   = r.RB_2D_DST_SIZE.PITCH
88bf215546Sopenharmony_ci  blit.addr    = r.RB_2D_DST_LO | (r.RB_2D_DST_HI << 32)
89bf215546Sopenharmony_ci  blit.base    = bos.base(blit.addr)
90bf215546Sopenharmony_ci  blit.ubwc_addr = r.RB_2D_DST_FLAGS_LO | (r.RB_2D_DST_FLAGS_HI << 32)
91bf215546Sopenharmony_ci  blit.ubwc_base = bos.base(blit.ubwc_addr)
92bf215546Sopenharmony_ci  blit.ubwc_pitch = r.RB_2D_DST_FLAGS_PITCH
93bf215546Sopenharmony_ci  blit.endaddr = 0  -- filled in later
94bf215546Sopenharmony_ci  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)
95bf215546Sopenharmony_ci
96bf215546Sopenharmony_ci  allblits[nallblits] = blit
97bf215546Sopenharmony_ci  nallblits = nallblits + 1
98bf215546Sopenharmony_ciend
99bf215546Sopenharmony_ci
100bf215546Sopenharmony_cifunction A5XX_TEX_CONST(pkt, size)
101bf215546Sopenharmony_ci  -- ignore any texture state w/ DEPTH=1, these aren't the 3d tex state we
102bf215546Sopenharmony_ci  -- are looking for
103bf215546Sopenharmony_ci
104bf215546Sopenharmony_ci  local base = pkt[4].BASE_LO | (pkt[5].BASE_HI << 32)
105bf215546Sopenharmony_ci  -- UBWC base on a5xx seems to be at the start of each miplevel, followed by pixels
106bf215546Sopenharmony_ci  -- somewhere past that.
107bf215546Sopenharmony_ci  local ubwc_base = base
108bf215546Sopenharmony_ci  local width0  = pkt[1].WIDTH
109bf215546Sopenharmony_ci  local height0 = pkt[1].HEIGHT
110bf215546Sopenharmony_ci  local depth0  = pkt[5].DEPTH
111bf215546Sopenharmony_ci
112bf215546Sopenharmony_ci  if (found_tex ~= 0) then
113bf215546Sopenharmony_ci    return
114bf215546Sopenharmony_ci  end
115bf215546Sopenharmony_ci  found_tex = 1
116bf215546Sopenharmony_ci
117bf215546Sopenharmony_ci  printf("Found texture state:\n  %ux%ux%u (%s, %s, UBWC=%s)\n",
118bf215546Sopenharmony_ci         width0, height0, depth0, pkt[0].FMT, pkt[0].TILE_MODE, tostring(pkt[3].FLAG))
119bf215546Sopenharmony_ci
120bf215546Sopenharmony_ci  -- Note that in some case the texture has some extra page or so
121bf215546Sopenharmony_ci  -- at the beginning:
122bf215546Sopenharmony_ci  local basebase = bos.base(base)
123bf215546Sopenharmony_ci  printf("base: 0x%x (0x%x)\n", base, basebase)
124bf215546Sopenharmony_ci  printf("ubwcbase: 0x%x (0x%x)\n", ubwc_base, bos.base(ubwc_base))
125bf215546Sopenharmony_ci
126bf215546Sopenharmony_ci  -- see if we can find the associated blits..  The blob always seems to
127bf215546Sopenharmony_ci  -- start from the lower (larger) mipmap levels and layers, so we don't
128bf215546Sopenharmony_ci  -- need to sort by dst address.  Also, while we are at it, fill in the
129bf215546Sopenharmony_ci  -- end-addr (at least for everything but the last blit)
130bf215546Sopenharmony_ci  local blits = {}
131bf215546Sopenharmony_ci  local nblits = 0
132bf215546Sopenharmony_ci  local lastblit = nil
133bf215546Sopenharmony_ci  for n = 0,nallblits-1 do
134bf215546Sopenharmony_ci    local blit = allblits[n]
135bf215546Sopenharmony_ci    --printf("blit addr: 0x%x (0x%x)\n", blit.addr, blit.base)
136bf215546Sopenharmony_ci    if blit.base == basebase and blit.addr >= base then
137bf215546Sopenharmony_ci      blits[nblits] = blit
138bf215546Sopenharmony_ci      nblits = nblits + 1
139bf215546Sopenharmony_ci      if lastblit then
140bf215546Sopenharmony_ci        lastblit.endaddr = blit.addr
141bf215546Sopenharmony_ci      end
142bf215546Sopenharmony_ci      lastblit = blit
143bf215546Sopenharmony_ci    end
144bf215546Sopenharmony_ci  end
145bf215546Sopenharmony_ci
146bf215546Sopenharmony_ci  printf("	{\n")
147bf215546Sopenharmony_ci  printf("		.format = %s,\n", pkt[0].FMT)
148bf215546Sopenharmony_ci  if (tostring(pkt[2].TYPE) == "A5XX_TEX_3D") then
149bf215546Sopenharmony_ci    printf("		.is_3d = true,\n")
150bf215546Sopenharmony_ci  end
151bf215546Sopenharmony_ci
152bf215546Sopenharmony_ci  printf("		.layout = {\n")
153bf215546Sopenharmony_ci  printf("			.tile_mode = %s,\n", pkt[0].TILE_MODE)
154bf215546Sopenharmony_ci  printf("			.ubwc = %s,\n", tostring(pkt[3].FLAG))
155bf215546Sopenharmony_ci
156bf215546Sopenharmony_ci  if (tostring(pkt[2].TYPE) == "A5XX_TEX_3D") then
157bf215546Sopenharmony_ci    printf("			.width0 = %d, .height0 = %d, .depth0 = %d,\n", width0, height0, depth0)
158bf215546Sopenharmony_ci  else
159bf215546Sopenharmony_ci    printf("			.width0 = %d, .height0 = %d,\n", width0, height0)
160bf215546Sopenharmony_ci  end
161bf215546Sopenharmony_ci
162bf215546Sopenharmony_ci  printf("			.slices = {\n")
163bf215546Sopenharmony_ci  local w = 0
164bf215546Sopenharmony_ci  local h = 0
165bf215546Sopenharmony_ci  local level = 0
166bf215546Sopenharmony_ci  repeat
167bf215546Sopenharmony_ci    local w = minify(width0, level)
168bf215546Sopenharmony_ci    local h = minify(height0, level)
169bf215546Sopenharmony_ci    local blit = get_first_blit(basebase, w, h)
170bf215546Sopenharmony_ci    if blit then
171bf215546Sopenharmony_ci      printf("				{ .offset = %d, .pitch = %u },\n",
172bf215546Sopenharmony_ci          blit.addr - base,
173bf215546Sopenharmony_ci          blit.pitch);
174bf215546Sopenharmony_ci    end
175bf215546Sopenharmony_ci    level = level + 1
176bf215546Sopenharmony_ci  until w == 1 and h == 1
177bf215546Sopenharmony_ci  printf("			},\n")
178bf215546Sopenharmony_ci
179bf215546Sopenharmony_ci  if pkt[3].FLAG then
180bf215546Sopenharmony_ci    printf("			.ubwc_slices = {\n")
181bf215546Sopenharmony_ci    level = 0
182bf215546Sopenharmony_ci    repeat
183bf215546Sopenharmony_ci      local w = minify(width0, level)
184bf215546Sopenharmony_ci      local h = minify(height0, level)
185bf215546Sopenharmony_ci      local blit = get_first_blit(basebase, w, h)
186bf215546Sopenharmony_ci      if blit then
187bf215546Sopenharmony_ci        printf("				{ .offset = %d, .pitch = %u },\n",
188bf215546Sopenharmony_ci            blit.ubwc_addr - ubwc_base,
189bf215546Sopenharmony_ci            blit.ubwc_pitch);
190bf215546Sopenharmony_ci      end
191bf215546Sopenharmony_ci      level = level + 1
192bf215546Sopenharmony_ci    until w == 1 and h == 1
193bf215546Sopenharmony_ci    printf("			},\n")
194bf215546Sopenharmony_ci  end
195bf215546Sopenharmony_ci
196bf215546Sopenharmony_ci  printf("		},\n")
197bf215546Sopenharmony_ci  printf("	},\n")
198bf215546Sopenharmony_ci  printf("\n\n")
199bf215546Sopenharmony_ciend
200bf215546Sopenharmony_ci
201