Skip to content

GL_INVALID_ENUM (1280) on first WebGL operation per frame with texture-array projection layers #227

@cedi-code

Description

@cedi-code

Environment:

  • Headset: Meta Quest 3 (v81.1034)
  • Browser: Meta Quest Browser v41.0
  • Access method: Port forwarding via Chrome from W11
  • WebXR API: immersive-vr with local-floor reference space
  • WebGL: WebGL2

Description

I noticed that in the sample github code, a texture-array from a projection layer never gets binded directly but always over a multiview extension.

So when I tried to bind the colorTexture via

gl.framebufferTextureLayer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, subImage.colorTexture, 0, subImage.imageIndex);

directly I seem to get a GL_INVALID_ENUM (1280) error on the first gl rendering operation when checking for errors. This does not happen if textureType: "texture"

Code for Reproduction

there is a small .html file that should reproduce this error message aswell (need to use portforwarding and check the logs)
Does not seem to appear when using webxr-layers-polyfill emulator.

webxr-standalone.html

// in webxr setup (after webgl is xr compatible):
const binding = new XRWebGLBinding(session, gl);
const projectionLayer = binding.createProjectionLayer({
  textureType: "texture-array",
  colorFormat: gl.RGBA8
});

session.updateRenderState({ layers: [projectionLayer] });

// In render loop:
function onXRFrame(time, frame) {
  const viewerPose = frame.getViewerPose(referenceSpace);
  if (!viewerPose) return;
  
  for (const view of viewerPose.views) {
    const subImage = binding.getViewSubImage(projectionLayer, view);
    
    gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer);
    gl.framebufferTextureLayer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, 
                              subImage.colorTexture, 0, subImage.imageIndex);
    
    const status = gl.checkFramebufferStatus(gl.FRAMEBUFFER);
    console.log("Status:", status); // Logs 36053 (FRAMEBUFFER_COMPLETE)
    
    gl.viewport(subImage.viewport.x, subImage.viewport.y, 
               subImage.viewport.width, subImage.viewport.height);
    
    // First operation - ERROR
    gl.clearColor(0, 0, view.eye === "left" ? 0 : 1, 0);
    console.log("Error before clear:", gl.getError()); // Logs 0 (NO_ERROR)
    gl.clear(gl.COLOR_BUFFER_BIT);
    console.log("Error after clear:", gl.getError()); // Logs 1280 (INVALID_ENUM)
    
    // Second operation - NO ERROR
    gl.clear(gl.COLOR_BUFFER_BIT);
    console.log("Error after second clear:", gl.getError()); // Logs 0 (NO_ERROR)
  }
  
  session.requestAnimationFrame(onXRFrame);
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions