cancel
Showing results for 
Search instead for 
Did you mean: 

OpenGL & Vulkan

Lilou
Journeyman III

OpenGL : Dual-source blending not working on AMD integrated GPU

Hi ! 

I'm having issues with dual-source blending (used for OIT) on my AMD integrated GPU when it's working fine on my Nvidia GPU.

First of all, some informations about my hardware and drivers.

Hardware: 

Dedicated GPU: NVIDIA Geforce RTX 2060

CPU: AMD Ryzen™ 7 4800H

Integrated GPU: AMD Radeon™ Graphics

Driver version:

AMD Radeon™ Graphics: 26.20.14048.2

To setup the blending functions I used the following code:

                glBlendFunci(0, GL_ONE, GL_ONE);
                glBlendFuncSeparatei(1, GL_ZERO, GL_ONE_MINUS_SRC_COLOR, GL_ONE, GL_ONE);

As a result on my AMD GPU, it looks like both of the draw buffers 0 & 1 are using the same blending function -> glBlendFunc(GL_ONE, GL_ONE);

I could also note that if I avoid using dual-source blending by doing two passes, it works just fine.

// First pass
glDrawBuffer(GL.COLOR_ATTACHMENT0);
glBlendFunc(GL_ONE, GL_ONE);
Draw();

// Second pass
glDrawBuffer(GL.COLOR_ATTACHMENT1);
glBlendFuncSeparate(GL_ZERO, GL_ONE_MINUS_SRC_COLOR, GL_ONE, GL_ONE);
Draw();

I suspect there is a bug in the drivers, is this a known issue ? 

 

Have a nice day !

 

0 Likes
1 Solution
Lilou
Journeyman III

Update:

@dorisyan  I found a solution to the issue I reported. 
In my original post I described a rendering pass that I set up the following way:

 

 glBlendFunci(0, GL_ONE, GL_ONE);
 glBlendFuncSeparatei(1, GL_ZERO, GL_ONE_MINUS_SRC_COLOR, GL_ONE, GL_ONE);

 

 But I fixed the issue by modifying the previous pass.

In the previous pass I needed to set the BlendFunc for another texture as in the next pass to:

 

glBlendFunc(GL_ONE, GL_ONE);

 

 It looks like the issue came from this line. It should be okay to use glBlendFunc to setup a texture with more than one draw buffer, it works just fine on Nvidia but to fix my problem I had to use:

 

 glBlendFunci(0, GL_ONE, GL_ONE);
 glBlendFunci(1, GL_ONE, GL_ONE);

 

 

In a  nutshell:

With the pseudo-code below, in the second pass, the dual source blending is not working with my AMD GPU.

 

 

// First pass
TextureA.Bind();
 glBlendFunc(GL_ONE, GL_ONE);

 Draw();
TextureA.Unbind();

// Second pass
TextureB.Bind();
 glBlendFunci(0, GL_ONE, GL_ONE);
 glBlendFuncSeparatei(1, GL_ZERO, GL_ONE_MINUS_SRC_COLOR, GL_ONE, GL_ONE);
 
 glActiveTexture(GL_TEXTURE1);
 glBindTexture(TextureA.Color0);

 glActiveTexture(GL_TEXTURE0);
 glBindTexture(TextureA.Color1);

 Draw();
TextureB.Unbind();

 

 

But if I use glBlendFunci in the first pass instead of glBlendFunc, the second pass goes well, no issue with my AMD GPU !

 

// First pass
TextureA.Bind();
 glBlendFunci(0, GL_ONE, GL_ONE);
 glBlendFunci(1, GL_ONE, GL_ONE);

 Draw();
TextureA.Unbind();

// Second pass
TextureB.Bind();
 glBlendFunci(0, GL_ONE, GL_ONE);
 glBlendFuncSeparatei(1, GL_ZERO, GL_ONE_MINUS_SRC_COLOR, GL_ONE, GL_ONE);
 
 glActiveTexture(GL_TEXTURE1);
 glBindTexture(TextureA.Color0);

 glActiveTexture(GL_TEXTURE0);
 glBindTexture(TextureA.Color1);

 Draw();
TextureB.Unbind();

 

I don't quite understand why but my issue is fixed so yay \o/

View solution in original post

0 Likes
3 Replies
dorisyan
Staff

Thanks for your report @Lilou , Could you please provide a minimal code which can reproduce this problem?

0 Likes

The trick is that at least linux Mesa AMD driver has this limitation -  when using dual source blending, the used blending function has to be GL_FUNC_ADD or GL_FUNC_SUBTRACT.  I do not know how the driver behaves in windows.  See this https://gitlab.freedesktop.org/mesa/mesa/-/issues/4183 for details.

0 Likes
Lilou
Journeyman III

Update:

@dorisyan  I found a solution to the issue I reported. 
In my original post I described a rendering pass that I set up the following way:

 

 glBlendFunci(0, GL_ONE, GL_ONE);
 glBlendFuncSeparatei(1, GL_ZERO, GL_ONE_MINUS_SRC_COLOR, GL_ONE, GL_ONE);

 

 But I fixed the issue by modifying the previous pass.

In the previous pass I needed to set the BlendFunc for another texture as in the next pass to:

 

glBlendFunc(GL_ONE, GL_ONE);

 

 It looks like the issue came from this line. It should be okay to use glBlendFunc to setup a texture with more than one draw buffer, it works just fine on Nvidia but to fix my problem I had to use:

 

 glBlendFunci(0, GL_ONE, GL_ONE);
 glBlendFunci(1, GL_ONE, GL_ONE);

 

 

In a  nutshell:

With the pseudo-code below, in the second pass, the dual source blending is not working with my AMD GPU.

 

 

// First pass
TextureA.Bind();
 glBlendFunc(GL_ONE, GL_ONE);

 Draw();
TextureA.Unbind();

// Second pass
TextureB.Bind();
 glBlendFunci(0, GL_ONE, GL_ONE);
 glBlendFuncSeparatei(1, GL_ZERO, GL_ONE_MINUS_SRC_COLOR, GL_ONE, GL_ONE);
 
 glActiveTexture(GL_TEXTURE1);
 glBindTexture(TextureA.Color0);

 glActiveTexture(GL_TEXTURE0);
 glBindTexture(TextureA.Color1);

 Draw();
TextureB.Unbind();

 

 

But if I use glBlendFunci in the first pass instead of glBlendFunc, the second pass goes well, no issue with my AMD GPU !

 

// First pass
TextureA.Bind();
 glBlendFunci(0, GL_ONE, GL_ONE);
 glBlendFunci(1, GL_ONE, GL_ONE);

 Draw();
TextureA.Unbind();

// Second pass
TextureB.Bind();
 glBlendFunci(0, GL_ONE, GL_ONE);
 glBlendFuncSeparatei(1, GL_ZERO, GL_ONE_MINUS_SRC_COLOR, GL_ONE, GL_ONE);
 
 glActiveTexture(GL_TEXTURE1);
 glBindTexture(TextureA.Color0);

 glActiveTexture(GL_TEXTURE0);
 glBindTexture(TextureA.Color1);

 Draw();
TextureB.Unbind();

 

I don't quite understand why but my issue is fixed so yay \o/

0 Likes