Debugging - JuanDiegoMontoya/Frogfood GitHub Wiki

Frogfood implements various features that I've found useful for debugging. Maybe you'll find them useful as well.

Shader assert

Asserts are an incredibly useful tool for verifying preconditions on the CPU. Why should the GPU be left out of the fun?

This feature uses GL_EXT_debug_printf and consists of a few simple macros that wrap debugPrintfEXT.

#define printf debugPrintfEXT

#ifdef GL_EXT_debug_printf
  #define ASSERT_MSG(x, msg) do { if (!bool(x)) { printf(msg); } } while(false)
  #define ASSERT(x) ASSERT_MSG(x, "Assertion failed!\n")
  #define UNREACHABLE ASSERT_MSG(false, "Unreachable path taken!\n")
#else
  #define ASSERT_MSG(x, msg) (int(0))
  #define ASSERT(x) (int(0))
  #define UNREACHABLE (int(0))
#endif

Unlike assert in C, it doesn't abort the shader or host program, but printing is useful enough.

Debug drawing from the GPU

With indirect drawing and a sprinkle of bindless magic, select shapes can be drawn from literally any shader:

// World-space AABB
bool TryPushDebugAabb(uint bufferIndex, DebugAabb box);

// Screen-space rect
bool TryPushDebugRect(uint bufferIndex, DebugRect rect);

// World-space line
bool TryPushDebugLine(Buffer lineBuffer, DebugLine line);

This interface can be found here.

This feature works by allocating a buffer for each shape containing an indirect draw struct and enough space for thousands of said shape instances. Any time one of the functions is called to push a debug shape, the instance count for that draw is incremented and the arguments are placed into a buffer. The CPU unconditionally issues an indirect draw command using this buffer to source the draw command and the arguments for each instance.

Drawing meshlet AABBs:

Drawing screen-space meshlet bounds (handy for debugging Hi-Z culling):

Drawing all paths traced by a chosen pixel (green: conceptual camera ray):

Every single ray for all pixels can be captured at once, resulting in a comical effect:

Despite that, it can be enlightening to discover the odd places that rays can get themselves lodged in.

Texture Viewer

This is basically a poor man's version of the texture viewer from RenderDoc. Only select textures support being visualized in this because I did not write a global texture manager.

image

Geometry Inspector

The complexity of the meshlet rendering pipeline meant that even a tool like RenderDoc could not always shows us the info we needed in its most useful form. This simple widget is used to download and then display all of the scene's geometry in a way that doesn't require manually chasing pointers.

image

Magnifier

Absolutely essential when pixel peeping is to be done, such as when implementing anti-aliasing. This widget works by simply drawing the scene image in an ImGui window with adjusted UVs. Don't forget to bring a nearest-neighbor sampler.

image