Avoid redundant OpenGL state changes during a draw - #47
Open
relh wants to merge 1 commit into
Open
Conversation
renderPbrPrimitive re-uploaded every uniform, rebound all texture units, and re-toggled blend/depth/cull for every primitive, then reset that state after each draw - ~55 GL calls per primitive. A glTF model with many primitives (the common case) pays this per primitive even when the frame constants and material are unchanged. This caches within one ctx.draw: - Uniform values are per-program GL state, so a PbrPassValues shadow dirty-checks the frame-level block (view/proj/lightSpace, lighting, fog, camera, tint, debugView, env) and uploads only on change. - The seven sampler-unit uniforms move to setupPbr (set once). - Material uniforms upload only when the material or its version changes; texture binds key on the actual GL id (so a late texture upload is still caught) with an epoch guard against ids recycled by glDeleteTextures. - Blend/depth-mask/cull/front-face go through an enable-state shadow. The binding/enable caches reset at the start of each ctx.draw (foreign GL between draws may have changed them) and after the library's own shadow/skybox passes; the uniform value cache is per-program and persists. Submission order, per-draw back-to-front blended flush, and post-draw GL state are unchanged, so output is identical. No API change. Measured on a dense scene (~1300 primitives, macOS GL): per-primitive uniform+bind cost drops from the bulk of renderPbrPrimitive's self time to noise; ~5 GL calls for an opaque same-material primitive vs ~55.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What changed
The OpenGL PBR renderer now skips unchanged uniforms, material settings, texture binds, and enable state within one
ctx.drawcall. State is reset at the draw boundary, so the public API and behavior stay the same.Result
In a dense scene, an opaque primitive using the same material drops from about 55 GL calls to about 5.
Checks
Upstream CI passes on every backend.