Performance Optimization

GPU timer queries (glQueryCounter, GL_TIME_ELAPSED; Vulkan timestamp queries), vendor profilers (Nsight Graphics, Radeon GPU Profiler, Intel GPA, Arm Mobile Studio, Snapdragon Profiler, Xcode), RenderDoc's event durations, and shader instruction/register st…

35.1 Where time goes

Fragment-bound: high resolution, expensive per-pixel shading, overdraw (many layers per pixel).

Vertex-bound: very dense meshes, expensive vertex shaders.

Bandwidth-bound: large textures, many render targets, HDR formats, post-processing chains.

CPU/driver-bound: many draw calls, state changes, uniform updates.

35.2 Shader optimization techniques

Move work up the pipeline: per-frame (CPU) → per-vertex → per-fragment; precompute constants on the CPU (e.g., normal matrix, light directions).

Avoid divergent branches in hot code; use mix/step for simple selection; uniform-driven branches are fine.

Minimize texture fetches; pack data into channels (e.g., ORM: occlusion/roughness/metallic), use mipmaps (cache-friendly), compressed formats (BC/ASTC/ETC2).

Reduce overdraw: front-to-back opaque sorting, depth pre-pass, early-Z (avoid discard and gl_FragDepth writes when possible).

Use appropriate precision on mobile (mediump).

Prefer built-ins (dot, mix, inversesqrt, fma) — they map to hardware instructions; vectorize operations (vec4 math instead of four scalar ops).

Avoid expensive functions in loops (pow, exp, trig) when cheaper forms exist (x * x instead of pow(x, 2.0)).

Limit loop counts, unroll small fixed loops, make bounds compile-time constants.

Shader variants via #define/specialization constants instead of runtime branching on many features.

Register pressure: large arrays and many live variables reduce occupancy.

Compute shaders: choose workgroup sizes as multiples of 32/64, use shared memory for reuse, avoid bank conflicts, coalesce memory access.

Half-resolution effects (SSAO, volumetrics, bloom) with bilateral upsampling.

Batching & instancing to reduce draw calls; indirect drawing for GPU-driven pipelines.

35.3 Measuring

GPU timer queries (glQueryCounter, GL_TIME_ELAPSED; Vulkan timestamp queries), vendor profilers (Nsight Graphics, Radeon GPU Profiler, Intel GPA, Arm Mobile Studio, Snapdragon Profiler, Xcode), RenderDoc's event durations, and shader instruction/register statistics from offline compilers (Radeon GPU Analyzer, Mali Offline Compiler, glslc + vendor tools).