1bf215546Sopenharmony_ci-- Parse logs from https://github.com/freedreno/freedreno/
2bf215546Sopenharmony_ci-- test-texturator.c to generate a src/freedreno/fdl/fd6_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("a630")
15bf215546Sopenharmony_cilocal found_tex = 0
16bf215546Sopenharmony_ci
17bf215546Sopenharmony_cilocal allblits = {}
18bf215546Sopenharmony_cilocal nallblits = 0
19bf215546Sopenharmony_ci
20bf215546Sopenharmony_cifunction get_next_blit(base, width, height, prev_blit)
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 and (not prev_blit or prev_blit.addr < blit.addr) 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 get_first_blit(base, width, height)
36bf215546Sopenharmony_ci  return get_next_blit(base, width, height, nil);
37bf215546Sopenharmony_ciend
38bf215546Sopenharmony_ci
39bf215546Sopenharmony_cifunction minify(val, lvls)
40bf215546Sopenharmony_ci  val = val >> lvls
41bf215546Sopenharmony_ci  if val < 1 then
42bf215546Sopenharmony_ci    return 1
43bf215546Sopenharmony_ci  end
44bf215546Sopenharmony_ci  return val
45bf215546Sopenharmony_ciend
46bf215546Sopenharmony_ci
47bf215546Sopenharmony_cifunction printf(fmt, ...)
48bf215546Sopenharmony_ci  return io.write(string.format(fmt, ...))
49bf215546Sopenharmony_ciend
50bf215546Sopenharmony_ci
51bf215546Sopenharmony_cifunction start_cmdstream(name)
52bf215546Sopenharmony_ci  io.write("Parsing " .. name .. "\n")
53bf215546Sopenharmony_ci  allblits = {}
54bf215546Sopenharmony_ci  nallblits = 0
55bf215546Sopenharmony_ciend
56bf215546Sopenharmony_ci
57bf215546Sopenharmony_cifunction draw(primtype, nindx)
58bf215546Sopenharmony_ci  local blit = {}
59bf215546Sopenharmony_ci
60bf215546Sopenharmony_ci  local type = "???";
61bf215546Sopenharmony_ci  if primtype == "BLIT_OP_SCALE" then
62bf215546Sopenharmony_ci    -- Just in case, filter out anything that isn't starting
63bf215546Sopenharmony_ci    -- at 0,0
64bf215546Sopenharmony_ci    if r.GRAS_2D_DST_TL.X ~= 0 or r.GRAS_2D_DST_TL.Y ~= 0 then
65bf215546Sopenharmony_ci      return
66bf215546Sopenharmony_ci    end
67bf215546Sopenharmony_ci
68bf215546Sopenharmony_ci    blit.width   = r.GRAS_2D_DST_BR.X + 1
69bf215546Sopenharmony_ci    blit.height  = r.GRAS_2D_DST_BR.Y + 1
70bf215546Sopenharmony_ci    blit.pitch   = r.RB_2D_DST_PITCH
71bf215546Sopenharmony_ci    blit.addr    = r.RB_2D_DST
72bf215546Sopenharmony_ci    blit.ubwc_addr = r.RB_2D_DST_FLAGS
73bf215546Sopenharmony_ci    blit.ubwc_pitch = r.RB_2D_DST_FLAGS_PITCH
74bf215546Sopenharmony_ci    type="blit";
75bf215546Sopenharmony_ci  else
76bf215546Sopenharmony_ci    blit.width   = r.GRAS_SC_WINDOW_SCISSOR_BR.X + 1
77bf215546Sopenharmony_ci    blit.height  = r.GRAS_SC_WINDOW_SCISSOR_BR.Y + 1
78bf215546Sopenharmony_ci    blit.pitch = r.RB_MRT[0].PITCH
79bf215546Sopenharmony_ci    blit.addr = r.RB_MRT[0].BASE
80bf215546Sopenharmony_ci    blit.ubwc_addr = r.RB_MRT_FLAG_BUFFER[0].ADDR
81bf215546Sopenharmony_ci    blit.ubwc_pitch = r.RB_MRT_FLAG_BUFFER[0].PITCH.PITCH
82bf215546Sopenharmony_ci    type="draw"
83bf215546Sopenharmony_ci  end
84bf215546Sopenharmony_ci  blit.base    = bos.base(blit.addr)
85bf215546Sopenharmony_ci  blit.ubwc_base = bos.base(blit.uwbc_addr)
86bf215546Sopenharmony_ci  blit.endaddr = 0  -- filled in later
87bf215546Sopenharmony_ci
88bf215546Sopenharmony_ci  printf("Found %s: 0x%x/%d (0x%x) %dx%d UBWC 0x%x/%d (0x%x)\n",
89bf215546Sopenharmony_ci         type, blit.addr, blit.pitch, blit.base, blit.width, blit.height, blit.ubwc_addr, blit.ubwc_pitch, blit.ubwc_base)
90bf215546Sopenharmony_ci
91bf215546Sopenharmony_ci  allblits[nallblits] = blit
92bf215546Sopenharmony_ci  nallblits = nallblits + 1
93bf215546Sopenharmony_ciend
94bf215546Sopenharmony_ci
95bf215546Sopenharmony_cifunction A6XX_TEX_CONST(pkt, size)
96bf215546Sopenharmony_ci  -- ignore any texture state w/ DEPTH=1, these aren't the 3d tex state we
97bf215546Sopenharmony_ci  -- are looking for
98bf215546Sopenharmony_ci
99bf215546Sopenharmony_ci  local base = pkt[4].BASE_LO | (pkt[5].BASE_HI << 32)
100bf215546Sopenharmony_ci  local ubwc_base = pkt[7].FLAG_LO | (pkt[8].FLAG_HI << 32)
101bf215546Sopenharmony_ci  local width0  = pkt[1].WIDTH
102bf215546Sopenharmony_ci  local height0 = pkt[1].HEIGHT
103bf215546Sopenharmony_ci  local depth0  = pkt[5].DEPTH
104bf215546Sopenharmony_ci
105bf215546Sopenharmony_ci  if (found_tex ~= 0) then
106bf215546Sopenharmony_ci    return
107bf215546Sopenharmony_ci  end
108bf215546Sopenharmony_ci  found_tex = 1
109bf215546Sopenharmony_ci
110bf215546Sopenharmony_ci  printf("Found texture state:\n  %ux%ux%u (%s, %s, MIN_LAYERSZ=0x%x, TILE_ALL=%s, UBWC=%s FLAG_LOG2=%ux%u %s)\n",
111bf215546Sopenharmony_ci         width0, height0, depth0, pkt[0].FMT, pkt[0].TILE_MODE, pkt[3].MIN_LAYERSZ, tostring(pkt[3].TILE_ALL), tostring(pkt[3].FLAG), pkt[10].FLAG_BUFFER_LOGW, pkt[10].FLAG_BUFFER_LOGH, tostring(pkt[0].SAMPLES))
112bf215546Sopenharmony_ci
113bf215546Sopenharmony_ci  -- Note that in some case the texture has some extra page or so
114bf215546Sopenharmony_ci  -- at the beginning:
115bf215546Sopenharmony_ci  local basebase = bos.base(base)
116bf215546Sopenharmony_ci  printf("base: 0x%x (0x%x)\n", base, basebase)
117bf215546Sopenharmony_ci  printf("ubwcbase: 0x%x (0x%x)\n", ubwc_base, bos.base(ubwc_base))
118bf215546Sopenharmony_ci
119bf215546Sopenharmony_ci  -- see if we can find the associated blits..  The blob always seems to
120bf215546Sopenharmony_ci  -- start from the lower (larger) mipmap levels and layers, so we don't
121bf215546Sopenharmony_ci  -- need to sort by dst address.  Also, while we are at it, fill in the
122bf215546Sopenharmony_ci  -- end-addr (at least for everything but the last blit)
123bf215546Sopenharmony_ci  local blits = {}
124bf215546Sopenharmony_ci  local nblits = 0
125bf215546Sopenharmony_ci  local lastblit = nil
126bf215546Sopenharmony_ci  for n = 0,nallblits-1 do
127bf215546Sopenharmony_ci    local blit = allblits[n]
128bf215546Sopenharmony_ci    --printf("blit addr: 0x%x (0x%x)\n", blit.addr, blit.base)
129bf215546Sopenharmony_ci    if blit.base == basebase and blit.addr >= base then
130bf215546Sopenharmony_ci      blits[nblits] = blit
131bf215546Sopenharmony_ci      nblits = nblits + 1
132bf215546Sopenharmony_ci      if lastblit then
133bf215546Sopenharmony_ci        lastblit.endaddr = blit.addr
134bf215546Sopenharmony_ci      end
135bf215546Sopenharmony_ci      lastblit = blit
136bf215546Sopenharmony_ci    end
137bf215546Sopenharmony_ci  end
138bf215546Sopenharmony_ci
139bf215546Sopenharmony_ci  printf("         {\n")
140bf215546Sopenharmony_ci  printf("            .format = %s,\n", pkt[0].FMT)
141bf215546Sopenharmony_ci  if (tostring(pkt[2].TYPE) == "A6XX_TEX_3D") then
142bf215546Sopenharmony_ci    printf("            .is_3d = true,\n")
143bf215546Sopenharmony_ci  end
144bf215546Sopenharmony_ci
145bf215546Sopenharmony_ci  printf("            .layout =\n");
146bf215546Sopenharmony_ci  printf("               {\n");
147bf215546Sopenharmony_ci  printf("                  .tile_mode = %s,\n", pkt[0].TILE_MODE)
148bf215546Sopenharmony_ci  printf("                  .ubwc = %s,\n", tostring(pkt[3].FLAG))
149bf215546Sopenharmony_ci  if (pkt[3].TILE_ALL) then
150bf215546Sopenharmony_ci    printf("                  .tile_all = true,\n")
151bf215546Sopenharmony_ci  end
152bf215546Sopenharmony_ci
153bf215546Sopenharmony_ci
154bf215546Sopenharmony_ci  if (tostring(pkt[0].SAMPLES) == "MSAA_ONE") then
155bf215546Sopenharmony_ci    -- Ignore it, 1 is the default
156bf215546Sopenharmony_ci  elseif (tostring(pkt[0].SAMPLES) == "MSAA_TWO") then
157bf215546Sopenharmony_ci    printf("                  .nr_samples = 2,\n")
158bf215546Sopenharmony_ci  elseif (tostring(pkt[0].SAMPLES) == "MSAA_FOUR") then
159bf215546Sopenharmony_ci    printf("                  .nr_samples = 4,\n")
160bf215546Sopenharmony_ci  else
161bf215546Sopenharmony_ci    printf("                  .nr_samples = XXX,\n")
162bf215546Sopenharmony_ci  end
163bf215546Sopenharmony_ci
164bf215546Sopenharmony_ci  printf("                  .width0 = %d,\n", width0)
165bf215546Sopenharmony_ci  printf("                  .height0 = %d,\n", height0)
166bf215546Sopenharmony_ci
167bf215546Sopenharmony_ci  if (tostring(pkt[2].TYPE) == "A6XX_TEX_3D") then
168bf215546Sopenharmony_ci    printf("                  .depth0 = %d,\n", depth0)
169bf215546Sopenharmony_ci  end
170bf215546Sopenharmony_ci
171bf215546Sopenharmony_ci  printf("                  .slices =\n")
172bf215546Sopenharmony_ci  printf("                     {\n")
173bf215546Sopenharmony_ci  local w = 0
174bf215546Sopenharmony_ci  local h = 0
175bf215546Sopenharmony_ci  local level = 0
176bf215546Sopenharmony_ci  repeat
177bf215546Sopenharmony_ci    local w = minify(width0, level)
178bf215546Sopenharmony_ci    local h = minify(height0, level)
179bf215546Sopenharmony_ci    local blit = get_first_blit(basebase, w, h)
180bf215546Sopenharmony_ci    if blit then
181bf215546Sopenharmony_ci      printf("                        {.offset = %d, .pitch = %u",
182bf215546Sopenharmony_ci          blit.addr - base,
183bf215546Sopenharmony_ci          blit.pitch);
184bf215546Sopenharmony_ci      if (tostring(pkt[2].TYPE) == "A6XX_TEX_3D") then
185bf215546Sopenharmony_ci        local second = get_next_blit(basebase, w, h, blit);
186bf215546Sopenharmony_ci        if second then
187bf215546Sopenharmony_ci          printf(", .size0 = %u", second.addr - blit.addr);
188bf215546Sopenharmony_ci        end
189bf215546Sopenharmony_ci      end
190bf215546Sopenharmony_ci      printf("},\n");
191bf215546Sopenharmony_ci    end
192bf215546Sopenharmony_ci    level = level + 1
193bf215546Sopenharmony_ci  until w == 1 and h == 1
194bf215546Sopenharmony_ci  printf("                     },\n")
195bf215546Sopenharmony_ci
196bf215546Sopenharmony_ci  if pkt[3].FLAG then
197bf215546Sopenharmony_ci    printf("                  .ubwc_slices =\n")
198bf215546Sopenharmony_ci    printf("                     {\n")
199bf215546Sopenharmony_ci    level = 0
200bf215546Sopenharmony_ci    repeat
201bf215546Sopenharmony_ci      local w = minify(width0, level)
202bf215546Sopenharmony_ci      local h = minify(height0, level)
203bf215546Sopenharmony_ci      local blit = get_first_blit(basebase, w, h)
204bf215546Sopenharmony_ci      if blit then
205bf215546Sopenharmony_ci        printf("                        {.offset = %d, .pitch = %u},\n",
206bf215546Sopenharmony_ci            blit.ubwc_addr - ubwc_base,
207bf215546Sopenharmony_ci            blit.ubwc_pitch);
208bf215546Sopenharmony_ci      end
209bf215546Sopenharmony_ci      level = level + 1
210bf215546Sopenharmony_ci    until w == 1 and h == 1
211bf215546Sopenharmony_ci    printf("                     },\n")
212bf215546Sopenharmony_ci  end
213bf215546Sopenharmony_ci
214bf215546Sopenharmony_ci  printf("               },\n")
215bf215546Sopenharmony_ci  printf("         },\n")
216bf215546Sopenharmony_ci  printf("\n\n")
217bf215546Sopenharmony_ciend
218bf215546Sopenharmony_ci
219