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