Purpose of #pragma debug(on) in GLSL Shaders
The #pragma debug(on) directive in OpenGL Shading
Language (GLSL) is an instruction to the GPU driver's shader compiler to
embed debugging information and prevent aggressive optimizations that
obscure the original source code. When preparing shaders for GPU
profiling and debugging tools, this directive ensures that the compiled
GPU assembly or intermediate representation can be mapped back to
human-readable GLSL code, allowing developers to accurately inspect
variables, step through instructions, and isolate rendering
bottlenecks.
By default, shader compilers in graphics drivers apply extensive optimizations to maximize runtime throughput. These optimizations include dead-code elimination, aggressive function inlining, register recycling, and instruction reordering. While beneficial for performance in production, these transformations alter the execution flow, making it difficult for graphics debuggers and profilers—such as RenderDoc, NVIDIA Nsight, or AMD Radeon Developer Tool Suite—to track individual lines of source code or read runtime variable states.
Adding #pragma debug(on) to the top of a shader forces
the compiler to prioritize traceability over maximum execution speed.
Specifically, it enables the following key functionalities during
profiling:
- Source-to-Assembly Mapping: It instructs the compiler to retain source-level metadata, allowing profilers to display the corresponding GLSL source code side-by-side with the low-level machine instructions or SPIR-V byte code.
- Variable State Retention: It discourages the compiler from eliminating intermediate variables or optimizing them out via register reuse, making variable inspection reliable during breakpoint debugging or event capture.
- Preserved Control Flow: It limits loop unrolling and branch flattening, ensuring the profiler reflects the logical execution paths written by the developer.
While essential for detailed profiling,
#pragma debug(on) alters performance metrics. Because
compiler optimizations are relaxed, execution time, register usage, and
pipeline occupancy will not accurately reflect final release
performance. Consequently, this directive is best utilized for
functional debugging, instruction-level stepping, and identifying
algorithmic flaws. Once fine-grained debugging is complete,
#pragma debug(on) should be removed or set to
#pragma debug(off) to profile realistic performance numbers
under full compiler optimization.