MRT: Writing to a render target based on a condition that involves a uniform?

Hello,

is it legal to write to a (second) render target based on a condition that involves a uniform?

For example:

uniform bool WriteColor1;

out vec4 Color0;
out vec4 Color1;

void main(void)
{
  Color0 = vec4(1.0);
  if (WriteColor1) Color1 = vec4(1.0);
}

The uniform WriteColor1 is only true when a second draw buffer was enabled.

Or do render targets always have to be written to avoid the generated shader program might do something unexpected?

I ask this because I am currently debugging a rendering problem and just noticed that something that involves a condition…

Color1 = WriteColor1 ? vec4(0.999) : vec4(0.998);

…seems to corrupt the output to Color0 (!). Note that I use 0.998 and 0.999 just to avoid that the shader optimizes the condition out.

Replacing that code line with an assignment without condition…

Color1 = vec4(0.999);

…does not corrupt the output to Color0.

I have 2 draw buffers activated and the uniform WriteColor1 is true (I checked its value).

So maybe it is my fault that I write to the second render target based on a condition?

Help is really appreciated!

is it legal to write to a (second) render target based on a condition that involves a uniform?

Define “legal”.

The result of a fragment shader is a fragment, containing a depth, stencil, and zero or more color values. User-defined FS output variables are assigned slots in that array. The value of any color in that array which is not assigned, or is not written to by the FS, is undefined.

The mapping from color array slots to actual buffers is part of the framebuffer’s state, specified by glDrawBuffers. This function can also discard a color array slot (by piping it to GL_NONE). However, if glDrawBuffers maps an array slot to an actual buffer, and the value of that slot is undefined (due to the above), then an undefined value will be written to that buffer.

It is legal to not write to an output variable. However, it only produces defined results if you also route that output color to GL_NONE. with the draw buffers state.

Do take note of one thing:

I ask this because I am currently debugging a rendering problem and just noticed that something that involves a condition…

Everything I said implies that there are no driver bugs. And what you just described is most certainly a driver bug. It is perfectly legal to write different values to a variable (output or otherwise) based on a condition like that.

The only way UB could happen is if you were writing nothing in one of those cases. And you’re not.

So complain to the IHV.

Thanks!

It started to happen after moving from Windows 8.1 to Windows 10 so maybe it is really a driver bug.