Reverse engineering tools

freedreno edited this page Aug 25, 2013 · 2 revisions

The freedreno git tree (and it's envytools submodule) contains a number of useful tools, and tests.

Guided Tour

  • tests-2d - simple 2d tests using blob libC2D2.so. Links against android bionic glibc and dynamic loader.
  • tests-3d - simple 3d GLES2 tests. Can also be built for glibc to run against gallium driver for comparison/debugging. When built by default to link against bionic, rendering happens to a pbuffer so you don't actually need an android UI
  • wrap - contains the src for libwrap.so which can be LD_PRELOAD'd to intercept cmdstream for 2d or 3d tests. Can be built for either glibc or bionic
  • opencl
  • fdre-a2xx - simple gl-like API and tests for a2xx. Not intended to be a complete replacement for GL, but the simple tests and shaders written in assembly provide an easier environment for experimentation.
  • fdre-a3xx - same as above but for a3xx.
  • util/
    • cffdump
    • pgmdump
    • disasm - disassembler (linked in to pgmdump and cffdump)
  • envytools/ - submodule for envytools, used for register decoding, etc
    • rnn/headergen2 - generates header files used by gallium driver, kernel, etc
    • rnn/librnn - register decoding lib used by cffdump
    • rnn/demsm - parsing tool that can be used w/ kernel traces of register read/write (in particular useful for display, but also can be used for gpu). The CONFIG_DRM_MSM_REGISTER_LOGGING option for msm drm/kms driver can be used build in support for register tracing
    • rnndb/ - the xml register database files for a2xx, a3xx, and display

For parts that can be built either for bionic or glibc, the BUILD variable controls which, for example:

  • make BUILD=glibc tests-3d, or
  • make BUILD=bionic tests-3d

Note that libwrap.so (currently) only supports the legacy kgsl driver from qcom android tree. For msm drm/kms driver you can simply use:

  # cat /sys/kernel/debug/dri/0/rd > logfile.rd

libwrap

Captures cmdstream into a .rd file, which is a simple binary file consisting of arbitrary number of sections, where each section has a type, length, and value. The first level cmdstream buffer is captured, and known/important gpu buffers are snapshot'd along with their gpu address. (cffdump needs this to follow IB's and other pointers in the cmdstream.)

cffdump

This tool decodes a2xx/a3xx commandstream captured in .rd file. It knows how to decode PM4 packets, follow branches in cmdstream (IB's), etc. And uses librnn to decode register write packets, and disasm to decode shaders. Useful arguments are:

  • --no-color - generate boring output
  • --summary - don't display every register write, but just summary of current register writes on each draw (DRAW_INDX) packet. Typically the order of register writes is not important, the more useful thing is just to know the current values on a draw call. Other packages, such as const-state write (uniforms, shaders, texture state) are still displayed.
  • --allregs - display all written registers in summary (don't ignore ones with zero values)

Some example .rd files can be found here.

Often a visual diff tool like meld is useful to compare different similar dumps from cffdump, to spot which register(s) have different settings:

cmdstream-diff

pgmdump

The tests-3d tests use the "GetProgramBinaryOES" extension to capture the shaders as generated by the compiler, which can be dumped with the pgmdump tool.

For a2xx the shaders are patched at runtime for vertex/attribute location/type. This is not needed for a3xx. But in both cases, alternate versions of the vertex shader are generated for binning/tiling.

For a3xx, the --expand argument will expand out the repeat instructions.