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