Using MSAA causes OpenGL errors with certain color-renderable formats

In our project, we use MSAA and have recently moved to use an “HDR” framebuffer using the R11G11B10F format, and when enabling multisampling we get INVALID_OPERATION errors from OpenGL when rendering, more specifically my drivers tell me:

Attempt to blit from a multisampled framebuffer and the bounds or format of the color buffer don't match with the draw framebuffer.

Example recreating the issue:

If you disable MSAA (set the last parameter of the RenderTargetTexture constructor to 1), the error goes away and all works as it should, but now you of course don’t have MSAA.

(Please note here I refer to the format as R11G11B10F, which is called TEXTURETYPE_UNSIGNED_INT_10F_11F_11F_REV in Babylon).

Looking more closely at the issue, I found that this issue is caused by the _getRGBAMultiSampleBufferFormat function in thinEngine.ts missing a lot of cases for color-renderable formats, such as R11G11B10F. So with this function, the multisampling framebuffer is created with RGBA8 instead, while the internal non-multisampled framebuffer you blit to is created with the R11G11B10F format which then errors when Babylon blits between these as their formats are incompatible. No error or warning is given by Babylon indicating you didn’t get the render target you requested.

Simply adding R11G11B10F as a case in the _getRGBAMultiSampleBufferFormat function makes it work as expected, and we’ve run this in our own environment at least quite a bit, and has worked great for us!

I’m not sure why the decision was made to separate the multisample buffer format from the non-multisample buffer format (as they’re usually the same), but maybe you’ve decided to not support certain formats, or any other reason I’m probably missing!
But the commons ones that I think it’s missing are:

  • R11G11B10F
  • RG16F
  • RG32F
  • R8, RG8

Nonetheless, it would be nice to get an error message from Babylon if I’m trying to create a render target with an incompatible/unsupported format, instead of this GL error which was fairly hard to track down why it gave an error.
And of course, preferably, we would like R11G11B10F to be supported here, as it’s a very nice format for simple HDR rendering without sacrificing framebuffer bandwidth :slight_smile:

All the best,

Amazing catch and definitely an oversight (let s call it a bug :wink: ) on our side.

Do you want to create a PR to fix it ? or do you want us to push it ?

We should indeed use R11G11B10F more often as well internally to be honest. It is such a nice cheap

I could definitely make a PR! Do you do any error checking for these things or do you just try create what the user wanted, and then let the context error if they made something that’s not supported on their system, or if they created a framebuffer with a non color-renderable format?
Gonna be differences between WebGL1/2 and extensions there of course, and I think number of supported of MSAA samples is defined per-format as well, but only queryable in WebGL2.

R11G11B10F is indeed a super nice format! On our devices it make several milliseconds of frametime difference (all integrated and mobile GPUs). However it can make for some really ugly yellow banding (due to the lower mantissa bits in the blue channel), but worked around that with some dithering in the imageProcessingFunctions shader, which helps a lot!

With and without dithering:

1 Like

Thanks a lot !!!

We usually try to create what the user want and handle fallback from webgl2 to webgl1 transparently.

Make it the simplest first and we can discuss on the PR :slight_smile:

Fixed by: Fix missing internal sized formats for MSAA render targets by rapid-images-tore-levenstam · Pull Request #14580 · BabylonJS/Babylon.js · GitHub

1 Like

Thanks again !!!