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