Developing Games on Intel Graphics
If you are gaming on graphics integrated in your Intel Processor, this is the place for you! Find answers to your questions or post your issues with PC games
Announcements
This forum offers only peer-to-peer support. Thank you!
Learn more about Developing Games on Intel Graphics
555 Discussions

OpenGL mix() function not working correctly with Minecraft shaders.

djmrFunnyMan
New Contributor II
2,124 Views

This is a continuation from https://community.intel.com/t5/Developing-Games-on-Intel/Driver-level-bugs-causing-issues-in-Minecraft-amp-OpenGL-shaders/td-p/1664368 which will be split into 3 separate reports.

The issue:

The OpenGL mix() function seems to not work correctly.

It produces NaN's in situations where AMD and Nvidia cards don't have such issues.
In this particular case the line of code affected is line 21 in blocklightColors.glsl (in the attached shaderpacks.zip)

 

vec3 torchBlockSpecialLightColor = mix(vec3(2.0, 0.87, 0.27), fireSpecialLightColor, 0.75);

 


Rudimentary investegation:

Doing this will fix the issue and make it behave as expected. This fix makes zero sense however as clamp(0.75, 0.0, 1.0) should do absolutely nothing to the 0.75

 

 

vec3 torchBlockSpecialLightColor = mix(vec3(2.0, 0.87, 0.27), fireSpecialLightColor, clamp01(0.75));  //this works as expected

 

 

clamp01 is just a simple function that looks like this (it's in commonFunctions.glsl)

 

 

float clamp01(float x) {
    return clamp(x, 0.0, 1.0);
}

 

 

What makes even less sense is that, not using the function and directly doing clamp(0.75, 0.0, 1.0) results in different broken behaviour (also a NaN but it doesn't spread over the entire screen anymore)

 

 

vec3 torchBlockSpecialLightColor = mix(vec3(2.0, 0.87, 0.27), fireSpecialLightColor, clamp(0.75, 0.0, 1.0));  //this is broken

 

 

This makes precisely zero sense as clamp01 is just clamp(x , 0.0, 1.0) so there should be absolutely no difference between the two.

The suspected culprit is malfunctioning constant folding.

Reproduction Steps

Preparation:
- Install Iris & Sodium for 1.21.4 : https://github.com/IrisShaders/Iris/blob/multiloader-new/docs/guide.md
- Unpack the shaderpacks.zip inside the (...)\AppData\Roaming\.minecraft folder
- Unpack the Driver Bug Test.zip inside the \AppData\Roaming\.minecraft\saves folder
- Go into options>video settings>shaderpacks and select "complementary unbound 5.4 + euphoria patches 1.5.2"
- Press apply

Reproduction:

- Open the Driver Bug Test world in-game
- Step on the pressure plate that says "NaN apocalypse"
- Press the button to place a torch

0 Kudos
12 Replies
karen_intel
Moderator
2,057 Views

@djmrFunnyMan thanks for splitting the cases.
I'll check this one too

Stay tuned

Karen

0 Kudos
Arturo_Intel
Moderator
363 Views

@djmrFunnyMan 

Hello, 

The official update status for this case can be found here: 
https://www.intel.com/content/www/us/en/support/articles/000102994.html

 

The team is working actively on this case

Will keep this case open for any new questions arise,

--Arturo

0 Kudos
djmrFunnyMan
New Contributor II
342 Views

There is a big misunderstanding in the support article. 

The direct call is what miscompiles. Using the helper function is a workaround to produce correct results.

Basically you mislabeled the malfunctioning and functioning examples (should be the opposite of how it is now).

0 Kudos
djmrFunnyMan
New Contributor II
342 Views

@Arturo_Intel Please check my reply above (I forgot to ping you)

0 Kudos
Arturo_Intel
Moderator
323 Views

Ow! Thanks for heads up!

I will change this ASAP.

-r2

djmrFunnyMan
New Contributor II
148 Views

@Arturo_Intel This misunderstanding is once again present in your repository README at https://github.com/Arturo-Intel/06497416/

So once more for clarity. The direct call is what miscompiles. Using the helper function is a workaround to produce correct results.

0 Kudos
djmrFunnyMan
New Contributor II
274 Views

@Arturo_Intel I have found another workaround.

vec3 torchBlockSpecialLightColor = mix(vec3(2.0, 0.87, 0.27), fireSpecialLightColor, 0.75); //this outputs a NaN
uniform float value = 0.75;
vec3 torchBlockSpecialLightColor = mix(vec3(2.0, 0.87, 0.27), fireSpecialLightColor, value); //this outputs the correct result


This tells me that the driver can be tricked into behaving correctly by changing how the float is provided, and using helper functions is not the only way of doing so.

0 Kudos
Arturo_Intel
Moderator
181 Views

Hello @djmrFunnyMan 

I’ve built and tested a standalone repro based on your shader, including a variant that compiles three fragment shader versions side by side with different torch weight expressions. The repro is available here: https://github.com/Arturo-Intel/06497416/

So far, I have not been able to reproduce the reported difference between the mix(..., 0.75) and mix(..., clamp01(0.75)) paths in this harness on the Intel systems I tested.

Given that, the next useful step is to move away from approximating the shader by hand and instead capture the exact final fragment shader source and the exact failing permutation from the real application on the affected Intel device. In other words, the most helpful data would be the fully preprocessed GLSL text and the exact set of active #defines and settings when the issue appears.

If possible, could you obtain this from your side? One practical way to do that is with RenderDoc, by capturing a frame on the affected system and inspecting the shader source used for the failing draw call. If available, it would be very helpful to share:

  • The full fragment shader source actually submitted for the failing permutation,

  • The associated define/configuration set,

  • The GPU model and driver version,

  • Any relevant runtime inputs, such as material ID or key uniform values.

Having that exact shader and permutation from the affected system would make it much more likely that we can turn this into a reliable repro and investigate the behavior further.

I will try to get this from my side too, but I think it will be faster from your side,

r2

0 Kudos
djmrFunnyMan
New Contributor II
178 Views

@Arturo_Intel I took two captures of the same scene

1. Capture with the issue present: link 

2. Capture with the workaround (issue "fixed"): link

The two captures should be nearly identical. But not exactly, given that some time has passed between the captured frames.

In both cases the problematic event has the EID 856

I have the decompiled (?) GLSL from during that drawcall (via the RenderDoc debug feature): link 
I don't know if it's useful.

It's interesting that, by following the code line after line using the debug feature, both captures reach the same result. So the debugger isn't able to reproduce the issue.


0 Kudos
djmrFunnyMan
New Contributor II
163 Views

@Arturo_Intel I took two more captures.

In those I turned off as many settings as possible to reduce the amount of code. And also used a slightly different reproduction method.

1. Capture with the issue present: link

2. Capture with the workaround: link

This time the event has EID of 887 in both captures.

0 Kudos
djmrFunnyMan
New Contributor II
162 Views

Also my GPU is the B580 with the latest driver version (32.0.101.861)

0 Kudos
djmrFunnyMan
New Contributor II
162 Views
0 Kudos
Reply