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