diff --git a/cffdump/CMakeLists.txt b/cffdump/CMakeLists.txt index c2e82210b24126b821ae16fb9479c4bfbff795d1..0f60882b967278afe1f54ec51bfc7cb47daccd66 100644 --- a/cffdump/CMakeLists.txt +++ b/cffdump/CMakeLists.txt @@ -4,9 +4,12 @@ cmake_minimum_required(VERSION 2.6) include_directories(${PROJECT_BINARY_DIR}) find_package(PkgConfig) -pkg_check_modules(LUA lua52) +pkg_check_modules(LUA lua53) if (NOT "${LUA_FOUND}") - pkg_check_modules(LUA lua) + pkg_check_modules(LUA lua52) + if (NOT "${LUA_FOUND}") + pkg_check_modules(LUA lua) + endif() endif() pkg_check_modules(LIBARCHIVE REQUIRED libarchive) diff --git a/cffdump/script.c b/cffdump/script.c index 11085c568ce337dc360361fa38dc9193d392f56c..611099a617183f51fa5579ca4067eb6997d85ede 100644 --- a/cffdump/script.c +++ b/cffdump/script.c @@ -27,6 +27,7 @@ */ #define _GNU_SOURCE +#define LUA_COMPAT_APIINTCASTS #include <stdio.h> #include <string.h> @@ -569,6 +570,12 @@ static const struct luaL_Reg l_bos[] = { {NULL, NULL} /* sentinel */ }; +static void openlib(const char *lib, const luaL_Reg *reg) +{ + lua_newtable(L); + luaL_setfuncs(L, reg, 0); + lua_setglobal(L, lib); +} /* called at start to load the script: */ int script_load(const char *file) @@ -579,9 +586,9 @@ int script_load(const char *file) L = luaL_newstate(); luaL_openlibs(L); - luaL_openlib(L, "bos", l_bos, 0); - luaL_openlib(L, "regs", l_regs, 0); - luaL_openlib(L, "rnn", l_rnn, 0); + openlib("bos", l_bos); + openlib("regs", l_regs); + openlib("rnn", l_rnn); ret = luaL_loadfile(L, file); if (ret) diff --git a/cffdump/scripts/texturator-to-unit-test.lua b/cffdump/scripts/texturator-to-unit-test.lua new file mode 100644 index 0000000000000000000000000000000000000000..f91e8dc19c14a609550a933eb96b2bf95dafa756 --- /dev/null +++ b/cffdump/scripts/texturator-to-unit-test.lua @@ -0,0 +1,186 @@ +-- Parse logs from https://github.com/freedreno/freedreno/ +-- test-texturator.c to generate a src/freedreno/fdl/fd6_layout_test.c +-- block. We figure out the offsets from blits, but there may be some +-- unrelated blits. So just save all of them until we find the +-- texture state. This gives us the base address, and the miplevel #0 +-- width/height/depth. Then work backwards from there finding the +-- blits to the same dst buffer and deducing the miplevel from the +-- minified dimensions + +local posix = require "posix" + +io.write("Analyzing Data...\n") + +local allblits = {} +local nallblits = 0 +local r = rnn.init("a630") +local found_tex = 0 + +function minify(val, lvls) + val = val >> lvls + if val < 1 then + return 1 + end + return val +end + +function printf(fmt, ...) + return io.write(string.format(fmt, ...)) +end + +function start_cmdstream(name) + io.write("Parsing " .. name .. "\n") + allblits = {} + nallblits = 0 +end + +function draw(primtype, nindx) + if primtype ~= "BLIT_OP_SCALE" then + return + end + + -- Just in case, filter out anything that isn't starting + -- at 0,0 + if r.GRAS_2D_DST_TL.X ~= 0 or r.GRAS_2D_DST_TL.Y ~= 0 then + return + end + + local blit = {} + + blit.width = r.GRAS_2D_DST_BR.X + 1 + blit.height = r.GRAS_2D_DST_BR.Y + 1 + blit.pitch = r.RB_2D_DST_SIZE.PITCH + blit.addr = r.RB_2D_DST_LO | (r.RB_2D_DST_HI << 32) + blit.base = bos.base(blit.addr) + blit.ubwc_addr = r.RB_2D_DST_FLAGS_LO | (r.RB_2D_DST_FLAGS_HI << 32) + blit.ubwc_base = bos.base(blit.uwbc_addr) + blit.ubwc_pitch = r.RB_2D_DST_FLAGS_PITCH.PITCH + blit.endaddr = 0 -- filled in later + printf("Found blit: 0x%x (0x%x) %dx%d\n", blit.addr, blit.base, blit.width, blit.height) + + allblits[nallblits] = blit + nallblits = nallblits + 1 +end + +function A6XX_TEX_CONST(pkt, size) + -- ignore any texture state w/ DEPTH=1, these aren't the 3d tex state we + -- are looking for + + local base = pkt[4].BASE_LO | (pkt[5].BASE_HI << 32) + local ubwc_base = pkt[7].FLAG_LO | (pkt[8].FLAG_HI << 32) + local width0 = pkt[1].WIDTH + local height0 = pkt[1].HEIGHT + local depth0 = pkt[5].DEPTH + + if (found_tex ~= 0) then + return + end + found_tex = 1 + + printf("Found texture state:\n %ux%ux%u (%s, %s, MIN_LAYERSZ=0x%x, TILE_ALL=%s, UBWC=%s FLAG_LOG2=%ux%u)\n", + 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) + + -- Note that in some case the texture has some extra page or so + -- at the beginning: + local basebase = bos.base(base) + printf("base: 0x%x (0x%x)\n", base, basebase) + printf("ubwcbase: 0x%x (0x%x)\n", ubwc_base, bos.base(ubwc_base)) + + -- see if we can find the associated blits.. The blob always seems to + -- start from the lower (larger) mipmap levels and layers, so we don't + -- need to sort by dst address. Also, while we are at it, fill in the + -- end-addr (at least for everything but the last blit) + local blits = {} + local nblits = 0 + local lastblit = nil + for n = 0,nallblits-1 do + local blit = allblits[n] + --printf("blit addr: 0x%x (0x%x)\n", blit.addr, blit.base) + if blit.base == basebase and blit.addr >= base then + blits[nblits] = blit + nblits = nblits + 1 + if lastblit then + lastblit.endaddr = blit.addr + end + lastblit = blit + end + end + + -- now go thru the relevant blits and print out interesting details + local level = 0 + local layer = 0 + local w = width0 -- track current width/height to detect changing + local h = height0 -- mipmap level + + printf(" {\n") + printf(" .format = %s,\n", pkt[0].FMT) + + printf(" .layout = {\n") + printf(" .tile_mode = %s,\n", pkt[0].TILE_MODE) + printf(" .ubwc = %s,\n", tostring(pkt[3].FLAG)) + printf(" .width0 = %d, .height0 = %d,\n", width0, height0) + printf(" .slices = {\n") + for n = 0,nblits-1 do + local blit = blits[n] + --printf("%u: %ux%u, addr=%x\n", n, blit.width, blit.height, blit.addr) + if w ~= blit.width or h ~= blit.height then + level = level + 1 + layer = 0 + + + if blit.width ~= minify(w, 1) or blit.height ~= minify(h, 1) then + printf("I am confused! %ux%u vs %ux%u\n", blit.width, blit.height, minify(w, 1), minify(h, 1)) + printf("addr=%x\n", blit.addr) + --return + end + + w = blit.width + h = blit.height + end + + printf(" { .offset = %d, .pitch = %u },\n", + blit.addr - base, + blit.pitch + ); + + layer = layer + 1 + end + printf(" },\n") + + layer = 0 + level = 0 + w = width0 + h = height0 + + printf(" .ubwc_slices = {\n") + for n = 0,nblits-1 do + local blit = blits[n] + --printf("%u: %ux%u, addr=%x\n", n, blit.width, blit.height, blit.addr) + if w ~= blit.width or h ~= blit.height then + level = level + 1 + layer = 0 + + if blit.width ~= minify(w, 1) or blit.height ~= minify(h, 1) then + printf("I am confused! %ux%u vs %ux%u\n", blit.width, blit.height, minify(w, 1), minify(h, 1)) + printf("addr=%x\n", blit.addr) + --return + end + + w = blit.width + h = blit.height + end + + printf(" { .offset = %d, .pitch = %u },\n", + blit.ubwc_addr - ubwc_base, + blit.ubwc_pitch + ); + + layer = layer + 1 + end + + printf(" },\n") + printf(" },\n") + printf(" },\n") + printf("\n\n") +end +