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

GLideN64 won't work on Linux with an Intel GPU (Mesa driver) #454

Closed
Mastergatto opened this issue May 1, 2015 · 96 comments
Closed

GLideN64 won't work on Linux with an Intel GPU (Mesa driver) #454

Mastergatto opened this issue May 1, 2015 · 96 comments

Comments

@Mastergatto
Copy link

But other video plugins will actually work on Mupen64plus. I have also tried to build the source, but (aside from few compilation errors that I have had to manually fix) GLideN64 still doesn't work.
In your blog you have said that GLideN64 now supports OpenGL 3.3, which is the higher version supported by the Mesa driver.

*** Error in `./mupen64plus': free(): invalid pointer: 0x00007f25b0d48340 ***
[1] 9340 abort

My system:
Debian GNU/Linux Jessie 8.0
Intel i7-4770K with HD Graphics 4600

@sergiobenrocha2
Copy link
Contributor

Minimum OpenGL is 4.2, where did you read that?

@Predator82Germany
Copy link
Contributor

I have only OpenGL 3.3 & plugin works

@sergiobenrocha2
Copy link
Contributor

I tried here with my Intel HD Graphics 4600:

python3: /home/sergio/Projects/Mupen64Plus/GLideN64/GLideN64_Public_Release_1/src/GLSLCombiner.cpp:265: GLuint _createShader(GLenum, const char*): Assertion `checkShaderCompileStatus(shader_object)' failed.
Aborted (core dumped)

With the binary from the release:

Core: Starting R4300 emulator: Dynamic Recompiler
Core: R4300: starting 64-bit dynamic recompiler at: 0x7f1e6a5214e0
OpenGL Error: invalid operation

@sergiobenrocha2
Copy link
Contributor

glxinfo | grep OpenGL:

OpenGL vendor string: Intel Open Source Technology Center
OpenGL renderer string: Mesa DRI Intel(R) Haswell Mobile 
OpenGL core profile version string: 3.3 (Core Profile) Mesa 10.1.3
OpenGL core profile shading language version string: 3.30
OpenGL core profile context flags: (none)
OpenGL core profile profile mask: core profile
OpenGL core profile extensions:
OpenGL version string: 3.0 Mesa 10.1.3
OpenGL shading language version string: 1.30
OpenGL context flags: (none)
OpenGL extensions:

@Mastergatto
Copy link
Author

Mine is:

OpenGL vendor string: Intel Open Source Technology Center
OpenGL renderer string: Mesa DRI Intel(R) Haswell Desktop 
OpenGL core profile version string: 3.3 (Core Profile) Mesa 10.4.2
OpenGL core profile shading language version string: 3.30
OpenGL core profile context flags: (none)
OpenGL core profile profile mask: core profile
OpenGL core profile extensions:
OpenGL version string: 3.0 Mesa 10.4.2
OpenGL shading language version string: 1.30
OpenGL context flags: (none)
OpenGL extensions:
OpenGL ES profile version string: OpenGL ES 3.0 Mesa 10.4.2
OpenGL ES profile shading language version string: OpenGL ES GLSL ES 3.0
OpenGL ES profile extensions:

@gonetz
Copy link
Owner

gonetz commented May 2, 2015

OpenGL core profile shading language version string: 3.30
OpenGL shading language version string: 1.30

If real shading language version is 1.30 - you're doomed.

The plugin dumps errors in gliden64.log file. Check, is it created?

@sergiobenrocha2
Copy link
Contributor

shader_compile error: 0:1(10): error: GLSL 3.30 is not supported. Supported versions are: 1.10, 1.20, 1.30, 1.00 ES, and 3.00 ES

@gonetz
Copy link
Owner

gonetz commented May 2, 2015

You need card/driver with GLSL 3.30 support. I think, this can be closed.

@sergiobenrocha2
Copy link
Contributor

"The development release of Mesa 10.1 may implement GL 3.3 on radeon drivers, but you need to request a 3.3 core profile. You are not doing this currently."

http://stackoverflow.com/questions/21565680/how-to-enable-opengl-3-3-using-mesa-10-1-on-ubuntu

@sergiobenrocha2
Copy link
Contributor

It seems you have to ask core profile 3.30, to enable it:

http://darmawan-salihun.blogspot.com.br/2015/03/glsl-330-in-intel-haswell-cpu.html

@Mastergatto
Copy link
Author

Before closing this ticket, we should give this a try.

@Mastergatto
Copy link
Author

Sadly, it's still the same with the public release 1.1. Is there a way to force OpenGL ES 3.0 on GLideN64? Because my driver supports it.

OpenGL ES profile shading language version string: OpenGL ES GLSL ES 3.0

@sergiobenrocha2
Copy link
Contributor

Trying last commit b219997:

mupen64plus: /home/sergio/Projects/Mupen64Plus/GLideN64/GLideN64/src/GLSLCombiner.cpp:270: GLuint _createShader(GLenum, const char*): Assertion `checkShaderCompileStatus(shader_object)' failed.
Aborted (core dumped)
Starting program: /usr/games/mupen64plus --gfx mupen64plus-video-GLideN64.so /home/sergio/Games/ROMs/Nintendo\ 64/Pokemon\ Stadium\ 2\ \(USA\).n64
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".

UI-Console: attached to core library 'Mupen64Plus Core' version 2.5.0
UI-Console:             Includes support for Dynamic Recompiler.
UI-Console:             Includes support for MIPS r4300 Debugger.
[New Thread 0x7fffedb02700 (LWP 4580)]
Core: Goodname: Pokemon Stadium 2 (U) [!]
Core: Name: POKEMON STADIUM 2   
Core: MD5: 1561C75D11CEDF356A8DDB1A4A5F9D5D
Core: CRC: 3571182 892FD06D
Core: Imagetype: .v64 (byteswapped)
Core: Rom size: 67108864 bytes (or 64 Mb or 512 Megabits)
Core: Version: 144C
Core: Manufacturer: Nintendo
Core: Country: USA
UI-Console Status: Cheat codes disabled.
UI-Console: using Video plugin: 'GLideN64' v2.0.0
UI-Console: using Audio plugin: 'Mupen64Plus SDL Audio Plugin' v2.5.0
UI-Console: using Input plugin: 'Mupen64Plus SDL Input Plugin' v2.5.0
UI-Console: using RSP plugin: 'Static Interpreter' v0.1.1
Input: 0 SDL joysticks were found.
Input: N64 Controller #1: Forcing default keyboard configuration
Input: 1 controller(s) found, 1 plugged in and usable in the emulator
Input Warning: Couldn't open rumble support for joystick #1
Input Warning: Couldn't open rumble support for joystick #2
Input Warning: Couldn't open rumble support for joystick #3
Input Warning: Couldn't open rumble support for joystick #4
Input: Mupen64Plus SDL Input Plugin version 2.5.0 initialized.
(II) Setting video mode 960x720...
Core: Setting video mode: 960x720
mupen64plus: /home/sergio/Projects/Mupen64Plus/GLideN64/GLideN64/src/GLSLCombiner.cpp:270: GLuint _createShader(GLenum, const char*): Assertion `checkShaderCompileStatus(shader_object)' failed.

Program received signal SIGABRT, Aborted.
0x00007ffff782dcc9 in __GI_raise (sig=sig@entry=6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:56
56  ../nptl/sysdeps/unix/sysv/linux/raise.c: No such file or directory.
(gdb) 
(gdb) 
(gdb) bt full
#0  0x00007ffff782dcc9 in __GI_raise (sig=sig@entry=6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:56
        resultvar = 0
        pid = 4579
        selftid = 4579
#1  0x00007ffff78310d8 in __GI_abort () at abort.c:89
        save_stage = 2
        act = {__sigaction_handler = {sa_handler = 0x7fffffffe298, sa_sigaction = 0x7fffffffe298}, sa_mask = {__val = {140737347271964, 140737166230680, 270, 93824995148688, 
              140737345914083, 4294967296, 140737488048800, 48684851456, 140737134795080, 4294967296, 0, 0, 0, 21474836480, 140737353990144, 140737347287088}}, 
          sa_flags = -322124568, sa_restorer = 0x7fffecccc420}
        sigs = {__val = {32, 0 <repeats 15 times>}}
#2  0x00007ffff7826b86 in __assert_fail_base (fmt=0x7ffff7977830 "%s%s%s:%u: %s%sAssertion `%s' failed.\n%n", 
    assertion=assertion@entry=0x7fffecccc4e8 "checkShaderCompileStatus(shader_object)", 
    file=file@entry=0x7fffecccc498 "/home/sergio/Projects/Mupen64Plus/GLideN64/GLideN64/src/GLSLCombiner.cpp", line=line@entry=270, 
    function=function@entry=0x7fffecccc420 "GLuint _createShader(GLenum, const char*)") at assert.c:92
        str = 0x555555d88680 "\260\207\330UUU"
        total = 4096
#3  0x00007ffff7826c32 in __GI___assert_fail (assertion=0x7fffecccc4e8 "checkShaderCompileStatus(shader_object)", 
    file=0x7fffecccc498 "/home/sergio/Projects/Mupen64Plus/GLideN64/GLideN64/src/GLSLCombiner.cpp", line=270, function=0x7fffecccc420 "GLuint _createShader(GLenum, const char*)")
    at assert.c:101
No locals.
#4  0x00007fffecc45b7d in ?? () from /usr/lib/x86_64-linux-gnu/mupen64plus/mupen64plus-video-GLideN64.so
No symbol table info available.
#5  0x00007fffecc46051 in InitShaderCombiner() () from /usr/lib/x86_64-linux-gnu/mupen64plus/mupen64plus-video-GLideN64.so
No symbol table info available.
#6  0x00007fffecc39446 in Combiner_Init() () from /usr/lib/x86_64-linux-gnu/mupen64plus/mupen64plus-video-GLideN64.so
No symbol table info available.
#7  0x00007fffecc53555 in OGLRender::_initData() () from /usr/lib/x86_64-linux-gnu/mupen64plus/mupen64plus-video-GLideN64.so
No symbol table info available.
#8  0x00007ffff528b142 in ?? () from /usr/lib/x86_64-linux-gnu/libmupen64plus.so.2
No symbol table info available.
#9  0x00007ffff528bb85 in CoreDoCommand () from /usr/lib/x86_64-linux-gnu/libmupen64plus.so.2
No symbol table info available.
#10 0x00005555555574f9 in ?? ()
No symbol table info available.
#11 0x00007ffff7818ec5 in __libc_start_main (main=0x5555555556d0, argc=4, argv=0x7fffffffdee8, init=<optimized out>, fini=<optimized out>, rtld_fini=<optimized out>, 
    stack_end=0x7fffffffded8) at libc-start.c:287
        result = <optimized out>
        unwind_buf = {cancel_jmp_buf = {{jmp_buf = {0, -6483079757029992351, 93824992247635, 140737488346848, 0, 0, 6483079758158731361, 6483096918158841953}, 
              mask_was_saved = 0}}, priv = {pad = {0x0, 0x0, 0x7fffffffdf10, 0x7ffff7ffe1c8}, data = {prev = 0x0, cleanup = 0x0, canceltype = -8432}}}
        not_first_call = <optimized out>
#12 0x0000555555557f7c in ?? ()
No symbol table info available.

@phly95
Copy link

phly95 commented Jun 23, 2015

If you check, Intel also has issues with windows #512 , so I guess there's no escape from the issue

@phly95
Copy link

phly95 commented Jun 23, 2015

Maybe you can get a proprietary driver for linux (or go to the open source version if you already have the official driver) to fix it though

@sergiobenrocha2
Copy link
Contributor

There is no intel proprietary driver for linux...

@Mastergatto
Copy link
Author

^ This.

So yeah, GLideN64 won't work even if compiled with -DGLES2=On, it'll always give a segfault....

EDIT: Pinging @gonetz , with GLES2 it actually doesn't create the gliden64.log file, just a segfault. What do you think?

@phly95
Copy link

phly95 commented Jun 25, 2015

what about this link? https://downloadcenter.intel.com/download/13815/Intel-Graphics-Drivers-for-Linux- I think these are the proprietary drivers

@sergiobenrocha2
Copy link
Contributor

This is Mesa, Xorg, kernel and other stuff updated...

@matthewharvey
Copy link
Contributor

After doing some experimenting, I was able to get the plugin to run* on my computer by running mupen64plus using the following command:

MESA_GL_VERSION_OVERRIDE=3.3COMPAT mupen64plus --gfx

This problem comes because Mesa does not really support compatibility profiles, but you can force them using the above environment variable. I think you can also force in drirc, but I haven't tried that.

  • by run, I mean manage to create a context. As soon as the emulator starts, I get the following error messages and I can hear the audio but can't see anything.
    Mesa warning: Unexpected target 0x9100 in store_texsubimage()
    Generated a 884 x 18 (15 kb) texture atlas
    Mesa: User error: GL_INVALID_OPERATION in glBlitFramebufferEXT(bad src/dst multisample pixel formats)

@matthewharvey
Copy link
Contributor

It won't run until you turn off multi-sampling. After doing that I'm playing Legend of Zelda Ocarina of Time on GLideN64 on my Intel Mesa graphics driver just fine.

@Mastergatto
Copy link
Author

For me it still doesn't work, even with MESA_GL_VERSION_OVERRIDE and with multi-sampling turned off. It still segfaults... What distro are you using?

@matthewharvey
Copy link
Contributor

Debian testing.

Without knowing what the segfaults are, I'd naturally try messing with the settings (for reference, I also ran into issues trying to turn on hi res textures). I'd also make sure that you're building from source and referencing the correct .so file when running mupen64plus (the --gfx option). If you post the output you're getting then maybe I can speculate more.

@Mastergatto
Copy link
Author

I have now resolved this issue by erasing mupen64plus's cfg file, looks like I have messed up with the settings in the past, maybe this is what has caused the segfault (strangely, it happened only with this graphic plugin). Now it works with a clean cfg file. Thanks!

Still, I won't close this issue because MESA_GL_VERSION_OVERRIDE is only a workaround and it won't fix properly the graphic plugin. We need to make GLideN64 request the proper OpenGL core profile as it has been said before.

@matthewharvey
Copy link
Contributor

Whether or not this issue should be closed is at least debatable. I tried forcing the application to request a core context, but the plugin definitely uses some deprecated (GL <= 3.0) functionality, and it didn't look trivial to get rid of those.
So the real question to me is whether removing deprecated functionality would be trivial (as it is at least somewhat desirable). And assuming that it is not, then the next question is whether Mesa actually supports compatibility mode.
If they actually support it, then it would be nice if they turned it on without any workarounds (I'll consider filing a bug report to ask). On the other hand, if they don't support it, then the current behaviour is really all we're going to get, and we can close this issue for now.

@Mastergatto
Copy link
Author

That's very unlikely, see here: http://lists.freedesktop.org/archives/mesa-dev/2012-August/026624.html
Unless someone steps up and brings OpenGL to the version 4.x by implementing GL_ARB_compatibility, which it's not trivial to be implemented...It likely won't happen and that would be a shame...

If you're going to file that bug report, I'll close this. Thanks.

@matthewharvey
Copy link
Contributor

After taking a look at the Mesa GL3.txt, you're absolutely right about the compatibility context.
I might look into exactly how much work it would be to convert the emulator to work with a core context. In the meantime, this isn't really a bug, but more of a design decision.
So the

@matthewharvey
Copy link
Contributor

Gah mobile browser.
So I won't file a bug report.

And the issue of whether or not to close the bug becomes an issue of practicality. If people who come here searching for a solution are more likely to find it if it is open then it might be worth while to keep it open.

@loganmc10
Copy link
Contributor

There are other things that could be done to try and improve performance, including mapping triangles.vertices and m_rect directly to the buffer instead of doing a memcpy.

like:

triangles.vertices = (SPVertex*) glMapBufferRange......

then doing all the work on triangles.vertices, then unmap before the draw call, but that would involve more drastic changes to the code, and I'm not sure if it would be much of a difference from the memcpy.

The other things is using VAO's instead of setting the glVertexAttribArray calls before each draw call, and that would involve at least 2000 VAO's, one for each buffer offset for each VBO. The information I read about VAO performance isn't that encouraging, which is why I didn't bother trying that out.

@loganmc10
Copy link
Contributor

So I can confirm that this (the vbo5 branch) allows the Core Profile to work, tested in RetroArch. I'm not really sure what more could be done to improve the performance. Any input from anyone would be appreciated.

@fzurita
Copy link
Contributor

fzurita commented Aug 24, 2016

You could have two separate code paths depending on a configuration option, one with the new way and one with the old. That way drivers that need the core profile, can switch that to enabled.

It could also be selected automatically at runtime through auto detection of the OpenGL renderer.

@loganmc10
Copy link
Contributor

Well you always need the core profile for OpenGL (3+, which is what GLideN64 supports), the only time you can "legally" choose between VBO's and client side arrays is in GLES2/3, so you could make the old way used by the GLESX ifdef to include GLES3/3.1.

I've updated the vbo5 branch since you tried it last, I realised I did my math wrong and it was creating a 20MB VBO, not a 2MB VBO like it should, so the performance might be better. It would be best to get VBO's working well since it is the "proper" way to do it, but if it can't get there, I think using the old way for GLES2/3 would be sufficient.

@fzurita
Copy link
Contributor

fzurita commented Aug 24, 2016

I just tested your latest update to the vbo5 branch. I don't see a difference in speed.

@loganmc10
Copy link
Contributor

Ya so this new code could be avoided by GLESX ifdefs since it doesn't offer any performance benefit. It is still required for OpenGL 3+ though, I assume the performance is going to be the same since laptops/desktops have much better memory bandwidth.

@fzurita
Copy link
Contributor

fzurita commented Aug 24, 2016

Memory bandwidth is much less of a concern for mobile since the memory is shared between the CPU and GPU. I think the calls you are making should be faster based on that. I don't get why they are slower.

@wareya
Copy link

wareya commented Aug 24, 2016

"Classic" GL drivers have a lot of hardware specific optimization. Modern GL makes certain hardware architectures more efficient since the driver has to keep track of less state translation, but it doesn't help with existing mobile architectures that much AFAIK.

Memory bandwidth isn't a given. People running 7-y/o desktop hardware (e.g. Evergreen AMD GPUs, like my old rig) should be able to expect 60 VI/s with fancy options like bloom and pixel shaded light disabled. Stuff that old doesn't have good memory bandwidth.

The performance penalty is probably just increased indirection. Also, GL has a lot of calls that seem like they should be non-blocking internally, but actually make the driver block on itself much like glfinish(), or only on specific dependants, etc. And drivers are allowed to implement more aggressive internal state blocks on such functions. It's a quagmire, but it's still better than old GL once you get everything sorted out; the problem is, there's no index of "GL functions to be careful with because drivers are allowed to make them behave slowly".

@loganmc10
Copy link
Contributor

Ya I guess you cant make assumptions about memory bandwidth. But either way, OpenGL 3.1+ mandates the use of VBOs as far as I understand it, and I can't think of any way to implement them faster than the way I have it in that vbo5 branch with glMapBufferRange (without some kind of major rewrite of how the draw calls happen).

@wareya
Copy link

wareya commented Aug 24, 2016

Think about it from the point of view of game engines. To a game engine, a VBO is a piece of, for archetypical example, model data that sits in memory for quite a while.

Most drivers only make VBO write access fast when it's created a specific way, and have high latency, even if bandwidth is high. Calling a function that requires a VBO to be in a consistent state induces high latency in such an access method, if you recently modified it.

Latency is the big problem for things like emulators using modern GL. You have to be exceptionally careful about reusing VBOs or calling functions that require them to be in a consistent state before said function can do its job and return.

@loganmc10
Copy link
Contributor

For me the vbo5 branch (glMapBufferRange) seems to perform just as good as the old way on my Mali device. I can't believe how poorly the Adreno devices I have perform, they have awful drivers. Anyway I'd need to do more testing but I'm willing to bet that the VBO approach performs the same as client side arrays on desktop OpenGL.

I think the best way forward would be to use client side arrays on GLES 2/3 and VBOs on regular OpenGL

@wareya
Copy link

wareya commented Aug 24, 2016

That's probably a good idea. If GLES allows them, it allows them for a reason.

There will probably be more room for optimizing VBOs - you can always do better with modern GL than oldschool GL on modern desktop GPUs - but that can come later.

What's the general flow of data from the microcode HLE (where it determines drawing commands and parses their state) until it gets around to the GPU? My old fork just replaced the oldschool GL with 1:1 modern GL equivalents, and it was pretty slow, maybe 80%-50% the speed of forcing mesa to (crashily) run the compat profile version.

@loganmc10
Copy link
Contributor

@wareya if you ever get a chance your shoukd try https://github.com/loganmc10/GLideN64/tree/vbo5 for performance, it supports the core profile, I'd be curious how it performs for you

@wareya
Copy link

wareya commented Aug 24, 2016

It runs at full speed, but I don't know how fast it is aside from that.

@gonetz
Copy link
Owner

gonetz commented Aug 24, 2016

@loganmc10 Are these changes enough to make the code compatible with 3.2 core profile? mupen64plus should be able to provide necessary core profile if you provide it with required minor and major GL version.

@wareya

What's the general flow of data from the microcode HLE

N64 display list usually pretty logical:

  • setup pixel pipeline (combiner, texture filtering, alpha-test etc)
  • setup textures (load tiles to TMEM, set tile size etc)
  • load matrices
  • load vertices
  • draw polygons

Plugin does not use GL until some Triangle command appears. Plugin tries to cache polygons, which share the same setup and draw them all by one draw command. drawTriangles setups pixel pipeline and textures, setups glVertexAttribArray and calls glDrawElements.

@wareya
Copy link

wareya commented Aug 24, 2016

Are these changes enough to make the code compatible with 3.2 core profile? mupen64plus should be able to provide necessary core profile if you provide it with required minor and major GL version.

These changes are enough to make the code compatible with 3.3 core profile. 3.3 is still used in places in shaders. However, mesa on linux supports 3.3 core right now, so it might be good enough. I don't know about OSX.

There are a couple changes that have to be made, but they're very minor: wareya@f5ef938

@loganmc10
Copy link
Contributor

@gonetz Yes I've tested this with RetroArch, which can request a core profile, and it looks like @wareya knows the changes to make to allow mupen64plus to do the same.

It still needs thorough testing, anything that issues a glDraw call (LLE triangles, DMA triangles, whatever drawLines deals with, texrects, post processing, etc..) could be affected, and I'm not sure what games trigger what situations.

@wareya
Copy link

wareya commented Aug 24, 2016

Note: GL defaults to the core profile. mupen64plus defaults to the compatibility profile because of its OSD. m64p is the only place where you have to specifically request a core profile.

@loganmc10
Copy link
Contributor

ok I made a "vbo" branch:

https://github.com/loganmc10/GLideN64/tree/vbo

with the commits squashed together and VBO's disabled for "GLESX"

@orbea
Copy link
Contributor

orbea commented Aug 26, 2016

mesa-2016.08.17_59bb821_master-x86_64-1_git
xf86-video-nouveau-1da8a93_2016.06.02_master-x86_64-1_git
OpenGL core profile version string: 4.3 (Core Profile) Mesa 12.1.0-devel (git-59bb821)

I tested this with GlupeN64 and found that did not work with an OpenGL core profile.

@loganmc10
Copy link
Contributor

In GLupeN64 you need to define CORE, so in the Makefile right after "-D__VEC4_OPT" add -DCORE

@orbea
Copy link
Contributor

orbea commented Aug 26, 2016

Thanks, that worked, I was able to get to the Dawn of the first day in Majora's Mask without any significant issues.

@loganmc10
Copy link
Contributor

This should be fixed now since the code refactor

@gonetz
Copy link
Owner

gonetz commented Mar 18, 2017

Who can test?

@loganmc10
Copy link
Contributor

The laptop I use runs Fedora and uses an Intel GPU, switching to using a core profile solved this problem for me.

@gonetz
Copy link
Owner

gonetz commented Mar 18, 2017

Ok, I close it then. It always can be reopened if the problem still exists.

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

No branches or pull requests