{"record":{"id":"c981f0e19f31647d","repo":"Comfy-Org/ComfyUI","slug":"ping-pong-framebuffer-is-not-complete","errorCode":null,"errorMessage":"Ping-pong framebuffer is not complete","messagePattern":"Ping-pong framebuffer is not complete","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"comfy_extras/nodes_glsl.py","lineNumber":495,"sourceCode":"        if num_passes > 1:\n            for _ in range(2):\n                pp_tex = gl.glGenTextures(1)\n                ping_pong_textures.append(pp_tex)\n                gl.glBindTexture(gl.GL_TEXTURE_2D, pp_tex)\n                gl.glTexImage2D(gl.GL_TEXTURE_2D, 0, gl.GL_RGBA32F, width, height, 0, gl.GL_RGBA, gl.GL_FLOAT, None)\n                gl.glTexParameteri(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MIN_FILTER, gl.GL_LINEAR)\n                gl.glTexParameteri(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MAG_FILTER, gl.GL_LINEAR)\n                gl.glTexParameteri(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_WRAP_S, gl.GL_CLAMP_TO_EDGE)\n                gl.glTexParameteri(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_WRAP_T, gl.GL_CLAMP_TO_EDGE)\n\n                pp_fbo = gl.glGenFramebuffers(1)\n                ping_pong_fbos.append(pp_fbo)\n                gl.glBindFramebuffer(gl.GL_FRAMEBUFFER, pp_fbo)\n                gl.glFramebufferTexture2D(gl.GL_FRAMEBUFFER, gl.GL_COLOR_ATTACHMENT0, gl.GL_TEXTURE_2D, pp_tex, 0)\n                gl.glDrawBuffers(1, [gl.GL_COLOR_ATTACHMENT0])\n\n                if gl.glCheckFramebufferStatus(gl.GL_FRAMEBUFFER) != gl.GL_FRAMEBUFFER_COMPLETE:\n                    raise RuntimeError(\"Ping-pong framebuffer is not complete\")\n\n        # Create input textures (reused for all batches)\n        for i in range(num_inputs):\n            tex = gl.glGenTextures(1)\n            input_textures.append(tex)\n            gl.glActiveTexture(gl.GL_TEXTURE0 + i)\n            gl.glBindTexture(gl.GL_TEXTURE_2D, tex)\n            gl.glTexParameteri(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MIN_FILTER, gl.GL_LINEAR)\n            gl.glTexParameteri(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MAG_FILTER, gl.GL_LINEAR)\n            gl.glTexParameteri(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_WRAP_S, gl.GL_CLAMP_TO_EDGE)\n            gl.glTexParameteri(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_WRAP_T, gl.GL_CLAMP_TO_EDGE)\n\n            loc = gl.glGetUniformLocation(program, f\"u_image{i}\")\n            if loc >= 0:\n                gl.glUniform1i(loc, i)\n\n        # Set static uniforms (once for all batches)\n        loc = gl.glGetUniformLocation(program, \"u_resolution\")","sourceCodeStart":477,"sourceCodeEnd":513,"githubUrl":"https://github.com/Comfy-Org/ComfyUI/blob/1c6d8d45b3693bfbb32385b410d813a7fd6be216/comfy_extras/nodes_glsl.py#L477-L513","documentation":"Raised in _render_shader_batch() when building the two ping-pong framebuffers used for multi-pass rendering (num_passes > 1): a single RGBA32F texture attached to GL_COLOR_ATTACHMENT0 did not yield a complete framebuffer. Because the main output FBO with the same texture format already succeeded, this almost always means resource exhaustion or texture/FBO id misuse rather than format support.","triggerScenarios":"Enabling multi-pass rendering at very large resolutions so several 16-byte-per-texel RGBA32F textures plus FBOs exceed VRAM or driver limits; contexts near GL_MAX_RENDERBUFFER_SIZE / texture limits; transient driver failure under memory pressure.","commonSituations":"4K+ multi-pass shader chains on small-VRAM GPUs; running alongside a large diffusion model already resident in VRAM.","solutions":["Reduce the output resolution or the number of passes.","Free VRAM before the GLSL stage (unload models, lower batch size) so the ping-pong textures fit.","Split the workflow so the GL render happens before large models are loaded.","If it persists at small sizes, suspect the driver and reproduce with a minimal EGL script."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"# multi-pass allocates ~2 extra RGBA32F textures: bytes ~= w*h*16*2\nw, h, vram_free = 4096, 4096, get_free_vram_bytes()\nassert w * h * 16 * 2 < vram_free * 0.5, \"ping-pong FBOs may not fit; lower resolution or pass count\"","typeGuard":null,"tryCatchPattern":"try:\n    out = run_glsl_multipass(...)\nexcept RuntimeError as e:\n    if \"Ping-pong framebuffer is not complete\" in str(e):\n        out = run_glsl_multipass(width=w // 2, height=h // 2)  # retry smaller\n    else:\n        raise","preventionTips":["Run GL multi-pass stages before loading large diffusion models into VRAM.","Prefer fewer passes and moderate resolutions on small-VRAM GPUs.","Free/unload models ahead of big GL renders."],"tags":["opengl","framebuffer","vram","multi-pass","glsl"],"backgroundTag":null,"analyzedSha":"1c6d8d45b3693bfbb32385b410d813a7fd6be216","analyzedAt":"2026-08-14T19:37:18.893Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}