Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Blank video output with Mupen64plus (GLES2/Raspberry Pi) #2837

Closed
cmitu opened this issue May 7, 2024 · 13 comments · Fixed by #2858
Closed

Blank video output with Mupen64plus (GLES2/Raspberry Pi) #2837

cmitu opened this issue May 7, 2024 · 13 comments · Fixed by #2858

Comments

@cmitu
Copy link

cmitu commented May 7, 2024

Hello,

starting with commit 1a0621d (bisected via git bisecgt), there's no video output on some N64 titles (i.e Cruis'n USA). There's sound and the input (keyboard in my case) still works, but there's a blank/black video output.
It may be related to the device/renderer used - a Rpi4 with GLES3, also reported to have issues on the Pi5. OS is current RaspiOS (based on Debian 12 bookworm, current stable) on 64bit ARM (aarch64). The log doesn't show much, see below.

Mupen64plus log
Mupen64Plus Console User-Interface Version 2.5.9

UI-Console: attached to core library 'Mupen64Plus Core' version 2.5.9
UI-Console:             Includes support for Dynamic Recompiler.
Core: Using full mem base
Core: Goodname: Cruis'n USA (U) (V1.2) [!]
Core: Name: Cruis'n USA
Core: MD5: 2838A9018AD2BCB8B7F6161C746A1B71
Core: CRC: B3402554 7340C004
Core: Imagetype: .z64 (native)
Core: Rom size: 8388608 bytes (or 8 Mb or 64 Megabits)
Core: Version: 1444
Core: Manufacturer: Nintendo
Core: Country: USA
UI-Console Status: Cheat codes disabled.
UI-Console: using Video plugin: 'GLideN64 rev.b021d8e' v2.0.0
UI-Console: using Audio plugin: 'Mupen64Plus SDL Audio Plugin' v2.5.9
Input: Using auto-config file at: '/opt/retropie/configs/n64/InputAutoCfg.ini'
UI-Console: using Input plugin: 'Mupen64Plus SDL Input Plugin' v2.5.9
UI-Console: using RSP plugin: 'Hacktarux/Azimer High-Level Emulation RSP Plugin' v2.5.9
Core Warning: Input plugin does not contain VRU support.
Core: input plugin did not specify a render callback; there will be no on screen display by the input plugin.
Input: 0 SDL joysticks were found.
Input: N64 Controller #1: Forcing default keyboard configuration
Input: Using auto-config file at: '/opt/retropie/configs/n64/InputAutoCfg.ini'
Input: 1 controller(s) found, 1 plugged in and usable in the emulator
Input Warning: Joystick #1 doesn't support rumble effect
Input Warning: Joystick #2 doesn't support rumble effect
Input Warning: Joystick #3 doesn't support rumble effect
Input Warning: Joystick #4 doesn't support rumble effect
Input: Mupen64Plus SDL Input Plugin version 2.5.9 initialized.
RSP: RSP Fallback disabled !
Core: Using video capture backend: dummy
Core: Game controller 0 (Standard controller) has a Memory pak plugged in
Core: Game controller 1 (Standard controller) has a Memory pak plugged in
Core: Game controller 2 (Standard controller) has a Memory pak plugged in
Core: Game controller 3 (Standard controller) has a Memory pak plugged in
Core: Using CIC type X102
Core: Setting video mode: 1280x1024
Audio: Using resampler speex
Audio: Initializing SDL audio subsystem...
Input Warning: Joystick #1 doesn't support rumble effect
Input Warning: Joystick #2 doesn't support rumble effect
Input Warning: Joystick #3 doesn't support rumble effect
Input Warning: Joystick #4 doesn't support rumble effect
Core: Initializing 4 RDRAM modules for a total of 8 MB
Core: Starting R4300 emulator: Dynamic Recompiler
Core: Init new dynarec
Audio: Initializing SDL audio subsystem...
^[Core Status: Stopping emulation.
Core: R4300 emulator finished.
Core Status: Rom closed.

Is there anything that could be added to the config to increase the logging or to better diagnose the issue ?

@Jj0YzL5nvJ
Copy link
Contributor

Jj0YzL5nvJ commented May 7, 2024

Try with:
export MESA_GLSL_CACHE_DISABLE=1

Or clear your shader cache.
rm -rf ${HOME}/.cache/mupen64plus ${HOME}/.cache/mesa_shader_cache

@cmitu
Copy link
Author

cmitu commented May 7, 2024

No, ignoring/erasing the shader cache doesn't seem to help - I still get a black screen. For a couple of launches, before invalidating the cache, I got a video output. Then, for the subsequent launches, using MESA_GLSL_CACHE_DISABLE=1 and clearing the cache, I got the same black screen.

@Jj0YzL5nvJ
Copy link
Contributor

Then seek for gliden64.log in the mupen64plus configuration folder.

@cmitu
Copy link
Author

cmitu commented May 8, 2024

Thanks.
The gliden64.log file shows:

2024/05/08,04:09:38.981,opengl_Utils.cpp:60,WARNING, "Could not query EGL extensions on this device"
2024/05/08,04:09:38.981,opengl_Utils.cpp:60,WARNING, "Could not query EGL extensions on this device"

and previously also printed:

2024/05/07,19:27:00.746,glsl_ShaderStorage.cpp:191,ERROR, "Error while writing shader with key key=0x3811FE23FFFFF7FB"
2024/05/07,19:27:00.746,glsl_ShaderStorage.cpp:191,ERROR, "Error while writing shader with key key=0x3851D6A3FFAFFFFF"
2024/05/07,19:27:00.746,glsl_ShaderStorage.cpp:191,ERROR, "Error while writing shader with key key=0x38FFFFFFFFFDF6FB

I think the latter messages have been printed after I cleared the shader cache, the former are printed right now when I start and get a blank video output.

@scurest
Copy link
Contributor

scurest commented May 8, 2024

I can repro the screen being fully black if I hack the snoise functions to always return 0.0. I suspect this is what's happening.

My guess is the GLSL mediump precision on the RPi is actually a float16. From a quick test, it looks like float16s don't have enough precision for the hash function to work (you ends up the fractional part of a number in the range where all fractional parts are 0). This would also explain why it doesn't happen on desktop, where everything is float32.

Can you see if this fixes it?

diff --git a/src/Graphics/OpenGLContext/GLSL/glsl_CombinerProgramBuilderCommon.cpp b/src/Graphics/OpenGLContext/GLSL/glsl_CombinerProgramBuilderCommon.cpp
index 901d17ab..1de49ab1 100644
--- a/src/Graphics/OpenGLContext/GLSL/glsl_CombinerProgramBuilderCommon.cpp
+++ b/src/Graphics/OpenGLContext/GLSL/glsl_CombinerProgramBuilderCommon.cpp
@@ -1007,8 +1007,8 @@ public:
 			"uniform float uNoiseSeed;								\n"
 			"lowp float snoise()									\n"
 			"{														\n"
-			"  mediump vec2 coord = floor(gl_FragCoord.xy/uScreenScale);	\n"
-			"  mediump vec3 p3 = vec3(uNoiseSeed, coord);			\n"
+			"  highp vec2 coord = floor(gl_FragCoord.xy/uScreenScale);	\n"
+			"  highp vec3 p3 = vec3(uNoiseSeed, coord);			\n"
 			// hash13 from https://www.shadertoy.com/view/4djSRW
 			"  p3 = fract(p3 * .1031);								\n"
 			"  p3 += dot(p3, p3.zyx + 31.32);						\n"
@@ -1063,13 +1063,13 @@ public:
 		if (config.generalEmulation.enableHiresNoiseDithering != 0)
 			// multiplier for higher res noise effect
 			m_part +=
-			"  lowp float mult = 1.0 + step(2.0, uScreenScale.x);	\n";
+			"  highp float mult = 1.0 + step(2.0, uScreenScale.x);	\n";
 		else
 			m_part +=
-			"  lowp float mult = 1.0;								\n";
+			"  highp float mult = 1.0;								\n";
 		m_part +=
-			"  mediump vec2 coord = floor(mult * (gl_FragCoord.xy/uScreenScale));	\n"
-			"  mediump vec3 p3 = vec3(uNoiseSeed, coord);				\n"
+			"  highp vec2 coord = floor(mult * (gl_FragCoord.xy/uScreenScale));	\n"
+			"  highp vec3 p3 = vec3(uNoiseSeed, coord);				\n"
 			// hash33 from https://www.shadertoy.com/view/4djSRW
 			"  p3 = fract(p3 * vec3(.1031, .1030, .0973));				\n"
 			"  p3 += dot(p3, p3.yxz+33.33);								\n"
@@ -1081,14 +1081,14 @@ public:
 		if (config.generalEmulation.enableHiresNoiseDithering != 0)
 			// multiplier for higher res noise effect
 			m_part +=
-			"  lowp float mult = 1.0 + step(2.0, uScreenScale.x);	\n";
+			"  highp float mult = 1.0 + step(2.0, uScreenScale.x);	\n";
 		else
 			m_part +=
-			"  lowp float mult = 1.0;								\n";
+			"  highp float mult = 1.0;								\n";
 		m_part +=
 			"														\n"
-			"  mediump vec2 coord = floor(mult * (gl_FragCoord.xy/uScreenScale));	\n"
-			"  mediump vec3 p3 = vec3(uNoiseSeed, coord);			\n"
+			"  highp vec2 coord = floor(mult * (gl_FragCoord.xy/uScreenScale));	\n"
+			"  highp vec3 p3 = vec3(uNoiseSeed, coord);			\n"
 			// hash13 from https://www.shadertoy.com/view/4djSRW
 			"  p3 = fract(p3 * .1031);								\n"
 			"  p3 += dot(p3, p3.zyx + 31.32);						\n"

@cmitu
Copy link
Author

cmitu commented May 8, 2024

@scurest thank you for the patch. Unfortunately it doesn't resolve the issue - still getting a black video. Here's a MESA shader cache dump taken from the start-up - https://gist.github.com/cmitu/57bd70c14e9f6914a96732f5844f1769.

@Jj0YzL5nvJ
Copy link
Contributor

@scurest, can you see #2507 too? I'm available as a guinea pig.

@scurest
Copy link
Contributor

scurest commented May 8, 2024

@cmitu Okay, thanks. I notice that if the shader has compilation errors it also produces a black screen. Compilation errors only get logged to gliden64.log in debug builds, ie. you need to pass -DCMAKE_BUILD_TYPE=Debug when you run cmake. Can you make sure you're using a debug build?

You can test whether logging of shader compilation errors is working with a patch like this

diff --git a/src/Graphics/OpenGLContext/GLSL/glsl_CombinerProgramBuilderCommon.cpp b/src/Graphics/OpenGLContext/GLSL/glsl_CombinerProgramBuilderCommon.cpp
index 901d17ab..e04c05bd 100644
--- a/src/Graphics/OpenGLContext/GLSL/glsl_CombinerProgramBuilderCommon.cpp
+++ b/src/Graphics/OpenGLContext/GLSL/glsl_CombinerProgramBuilderCommon.cpp
@@ -1073,7 +1073,7 @@ public:
 			// hash33 from https://www.shadertoy.com/view/4djSRW
 			"  p3 = fract(p3 * vec3(.1031, .1030, .0973));				\n"
 			"  p3 += dot(p3, p3.yxz+33.33);								\n"
-			"  return fract((p3.xxy + p3.yxx)*p3.zyx);					\n"
+			"  return adsfhdsakjhfjlksahliurhsadsakjdfhl;				\n"
 			"}															\n"
 			"lowp float snoiseA()									\n"
 			"{														\n"

which will definitely trigger an error.

Also make sure to clear the shader cache before testing.

@Jj0YzL5nvJ I don't understand the connection to this issue.

@Jj0YzL5nvJ
Copy link
Contributor

I don't understand the connection to this issue.

It's very likely a float precision issue as well. That hardware originally only had support for OpenGL 2.0, but later received support for OpenGL 3.3 in software.

It works with EnableInaccurateTextureCoordinates=True but fails with EnableInaccurateTextureCoordinates=False, and not generate errors, I suspect the driver might be truncating the precision of some shaders to maintain performance.

If it were possible to know exactly what the driver doesn't like, a special path/hack could be created for that hardware.

@cmitu
Copy link
Author

cmitu commented May 9, 2024

Can you make sure you're using a debug build?

Thank you. I've switched to a Debug build and the behavior/logging is changed.

Running the emulator crashes outright because of an assert:

....
Input: Mupen64Plus SDL Input Plugin version 2.5.9 initialized.
RSP: RSP Fallback disabled !
Core Status: Selected state slot: 3
Core: Using video capture backend: dummy
Core: Game controller 0 (Standard controller) has a Memory pak plugged in
Core: Game controller 1 (Standard controller) has a Memory pak plugged in
Core: Game controller 2 (Standard controller) has a Memory pak plugged in
Core: Game controller 3 (Standard controller) has a Memory pak plugged in
Core: Using CIC type X102
Core: Setting video mode: 1280x1024

mupen64plus: /home/pi/RetroPie-Setup/tmp/build/mupen64plus/GLideN64/src/Graphics/OpenGLContext/GLSL/glsl_CombinerProgramBuilder.cpp:514: graphics::CombinerProgram* glsl::CombinerProgramBuilder::buildCombinerProgram(Combiner&, Combiner&, const CombinerKey&): Assertion `Utils::checkProgramLinkStatus(program)' failed.

The gliden64.log log file contains the shader linking error - https://pastebin.com/9HV0SBqJ

@scurest
Copy link
Contributor

scurest commented May 9, 2024

Please try

diff --git a/src/Graphics/OpenGLContext/GLSL/glsl_CombinerProgramBuilderCommon.cpp b/src/Graphics/OpenGLContext/GLSL/glsl_CombinerProgramBuilderCommon.cpp
index 901d17ab..5ef84042 100644
--- a/src/Graphics/OpenGLContext/GLSL/glsl_CombinerProgramBuilderCommon.cpp
+++ b/src/Graphics/OpenGLContext/GLSL/glsl_CombinerProgramBuilderCommon.cpp
@@ -1004,11 +1004,11 @@ public:
 	ShaderNoise(const opengl::GLInfo & _glinfo)
 	{
 		m_part =
-			"uniform float uNoiseSeed;								\n"
+			"uniform mediump float uNoiseSeed;						\n"
 			"lowp float snoise()									\n"
 			"{														\n"
-			"  mediump vec2 coord = floor(gl_FragCoord.xy/uScreenScale);	\n"
-			"  mediump vec3 p3 = vec3(uNoiseSeed, coord);			\n"
+			"  highp vec2 coord = floor(gl_FragCoord.xy/uScreenScale);	\n"
+			"  highp vec3 p3 = vec3(uNoiseSeed, coord);			\n"
 			// hash13 from https://www.shadertoy.com/view/4djSRW
 			"  p3 = fract(p3 * .1031);								\n"
 			"  p3 += dot(p3, p3.zyx + 31.32);						\n"
@@ -1068,8 +1068,8 @@ public:
 			m_part +=
 			"  lowp float mult = 1.0;								\n";
 		m_part +=
-			"  mediump vec2 coord = floor(mult * (gl_FragCoord.xy/uScreenScale));	\n"
-			"  mediump vec3 p3 = vec3(uNoiseSeed, coord);				\n"
+			"  highp vec2 coord = floor(mult * (gl_FragCoord.xy/uScreenScale));	\n"
+			"  highp vec3 p3 = vec3(uNoiseSeed, coord);				\n"
 			// hash33 from https://www.shadertoy.com/view/4djSRW
 			"  p3 = fract(p3 * vec3(.1031, .1030, .0973));				\n"
 			"  p3 += dot(p3, p3.yxz+33.33);								\n"
@@ -1087,8 +1087,8 @@ public:
 			"  lowp float mult = 1.0;								\n";
 		m_part +=
 			"														\n"
-			"  mediump vec2 coord = floor(mult * (gl_FragCoord.xy/uScreenScale));	\n"
-			"  mediump vec3 p3 = vec3(uNoiseSeed, coord);			\n"
+			"  highp vec2 coord = floor(mult * (gl_FragCoord.xy/uScreenScale));	\n"
+			"  highp vec3 p3 = vec3(uNoiseSeed, coord);			\n"
 			// hash13 from https://www.shadertoy.com/view/4djSRW
 			"  p3 = fract(p3 * .1031);								\n"
 			"  p3 += dot(p3, p3.zyx + 31.32);						\n"

@cmitu
Copy link
Author

cmitu commented May 9, 2024

@scurest Thank you for the patch - after applying it now video output shows up, no longer a black screen.

@Rosalie241
Copy link
Contributor

@scurest could you PR that patch? it fixes rendering on my pinebook pro aswell with GLES.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants