Opened 2 years ago

Last modified 23 months ago

#13169 new defect

MYST3: missing scene transition effect on PowerPC (big-endian) machines on all OSes

Reported by: kas1e Owned by:
Priority: normal Component: Engine: Myst3
Version: Keywords: big endian, BE, Myst3, AmigaOS
Cc: kas1e Game: Myst 3: Exile

Description (last modified by kas1e)

While testing AmigaOS4 builds of ScummVM (v2.5.0 and daily build from 25.12.2021) find out a rendering issue.

The issue is that switch between scenes in Myst3 does not have that nice cross-fade effect when one image is fade out and another one fade it, making one image replace another with tasty cross-fade effect. Instead, we have or just a white screen for a time while the cross-fade effect should happen or a bit of visual trash (depends on the drivers we use).

If we use an older version of our drivers called MiniGL we have such a visuall mess:

https://youtu.be/ndhmxNXlLH4?t=78

If watch carefully between switching of scenes then instead of effect we have some purple vertical lines all over the screen for a time of effect. Mean that no-cross-fade happens, but nothing instead and unitialized stuff have place.

And that if I use another more modern OpenGL driver called GL4ES:

https://youtu.be/KiDJ3ox51lU?t=37

There all visibly better. Just instead of a color mess, we have a white screen for the time while the effect should happen and when a new scene happens.

When I test the same version of the game but on win32/x64 then all fine means it's probably a Big-Endian issue.

If needs any more details or tests just ask :)

Thanks!

Change History (22)

comment:1 by BeWorld2018, 2 years ago

I can confirm here, i have same with transition effect
I test with OpenGL/OpenGL but with Software mode, it's ok.

Platform : MorphOS

comment:2 by kas1e, 2 years ago

Yes, can confirm that on AmigaOS4 effect also works in software mode.

That probably mean that OpenGL-based code in Myst3 needs to be byte-swapped when handling of this effect happens ? (software renderer seems to be Endian aware and that is why it works imho?)

Last edited 2 years ago by kas1e (previous) (diff)

comment:3 by kas1e, 2 years ago

Summary: Myst III Exile: missing scene transition effect on PowerPC (big-endian) machines under AmigaOS4Myst III Exile: missing scene transition effect on PowerPC (big-endian) machines on all OSes

comment:4 by kas1e, 2 years ago

At the moment we only reach to the point that seems that it can be be a bug in glCopyTexImage2D() in all 3 realisation of GL drivers : MiniGL, OGLES2 and MorphOS GL.

To be 100% sure i will try to build ScummVM for LinuxPPC under MESA to see how it will reacts there. If bug still will be there, then it probabaly something about Endianes, if bug will be not there, then it will mean indeed bug in all the amigaos4 and morphos driver realisations.

comment:5 by lephilousophe, 2 years ago

I managed to reproduce the white screen bug using GL4ES and Mesa on Linux.

It's due to the fact that GL4ES doesn't mark its texture object as valid when using glCopyTexImage2D.
A call to glTexImage2D before corrects the problem although it shouldn't be needed.

What happens if you use the following patch?
Here, with GL4ES it works.

  • engines/myst3/gfx_opengl_texture.cpp

    a b void OpenGLTexture::copyFromFramebuffer(const Common::Rect &screen) {  
    135135               internalHeight = upperPowerOfTwo(height);
    136136               internalWidth = upperPowerOfTwo(width);
    137137       }
    138138
    139139       glBindTexture(GL_TEXTURE_2D, id);
     140       glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, internalWidth, internalHeight, 0, internalFormat, GL_UNSIGNED_BYTE, nullptr);
    140141       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    141142       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    142143
    143144       glCopyTexImage2D(GL_TEXTURE_2D, 0, internalFormat, screen.left, screen.top, internalWidth, internalHeight, 0);
    144145}

in reply to:  5 comment:6 by kas1e, 2 years ago

@lephilousophe

What happens if you use the following patch?
Here, with GL4ES it works.

Thanks for taking more attention on it ! Much apprecated :) But we do test yesterday with you the same path and ut wasn't working :) But i tried just in case another time, exactly what you quote there : nope, no cross-fade effect visibly.

Maybe you reproduce different "white" bug ? My one as shown on video is more like missng cross-fade effect and instead one image just overwrte another one, but in the time where we should have cross-fade we have nothng (or mess/white/etc depends on the driver)

comment:7 by kas1e, 2 years ago

Description: modified (diff)

comment:8 by kas1e, 2 years ago

PS. I tested it on MiniGL (opengl) and OGLES2 (opengl with shaders) both have issue even after path. But didn't tested with GL4ES at the moment.

comment:9 by BeWorld2018, 2 years ago

Version 1, edited 2 years ago by BeWorld2018 (previous) (next) (diff)

comment:10 by kas1e, 2 years ago

@BeWorld2018

Yeah, effect didn't works, just when it should happens in this time we randomly have stuff put on screen, and depends on drivers/memory layouts we have or trash, or white , or anyting else. But main point is that we have no cross-fade effect by some reassons.

comment:11 by lephilousophe, 2 years ago

@kas1e and @BeWorld2018

I don't understand how it renders now with the patch.
Is it possible to make a screenshot in the middle of the transition?
If it's too fast, you can change the setting in scummvm.ini file by setting transition_speed to something like -400 (note the minus sign).

Another test is possible although this looks more like a workaround.

By looking at MiniGL code, one can see that glReadPixels calls W3D_FlushFrame and W3D_WaitIdle before reading pixels. This is not done in glCopyTexImage2D.
The main problem with the workaround is that I am not sure MiniGL will issue the W3D_FlushFrame when doing glFinish.

  • engines/myst3/gfx_opengl_texture.cpp

    diff --git a/engines/myst3/gfx_opengl_texture.cpp b/engines/myst3/gfx_opengl_texture.cpp
    index bae85ba2e7f..40f07c44dfe 100644
    a b void OpenGLTexture::copyFromFramebuffer(const Common::Rect &screen) {  
    139139       glBindTexture(GL_TEXTURE_2D, id);
    140140       glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, internalWidth, internalHeight, 0, internalFormat, GL_UNSIGNED_BYTE, nullptr);
    141141       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    142142       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    143143
     144       // Ensure everything is rendered before capturing framebuffer
     145       glFinish();
     146
    144147       glCopyTexImage2D(GL_TEXTURE_2D, 0, internalFormat, screen.left, screen.top, internalWidth, internalHeight, 0);
    145148}
    146149
    147150} // End of namespace Myst3
    148151

comment:12 by kas1e, 2 years ago

@lephilousophe

Another test is possible although this looks more like a workaround.

Tried "glFlush()" patch : no, same issue.

Is it possible to make a screenshot in the middle of the transition?
If it's too fast, you can change the setting in scummvm.ini file by setting transition_speed to something like -400 (note the minus sign).

Done, there are video with -400 and both patches applied (glTexImage2D one and glFlush one):

OGLES2 (opengl with shaders): https://youtu.be/ojY0i2yvtXI

MiniGL (opengl): https://youtu.be/myh_5rZuL-o

See how interesting .. With OGLES2 we can see that between scenes swap, the whole texture is "flipped". Now, when effect should happens, flipped texture are shown for a while (for most of time of effect) and then, at the very end, i can see how cross-fade effect take place. But instead of full time, it take just 1/10 of time or something.

Then, if we check video with MiniGL rendering, there we instead have some different stuff, and not flipped texture, but shifted one, and being "purple", and then also we can see that for almost all time of cross-fade effect we have that "purple shifted texture" and at the end cross-fade effect taking 1/10 of the time it should take.

That make me think, that in both cases we like hit one issue : we use old/previous parts of video memory or something. The "mess" in minigl we have is that because we see that "shiftet purple stuff", just on fast-speed it looks like mess. And with OGLES2 we have no mess, because in the time we should have effect, texture just flipped, but no other color, so for us it like nothing happens.

It can be some issues with timing values or something, maybe some integer overflows somewhere ?

comment:13 by lephilousophe, 2 years ago

OK

OGLES2 rendering is OK except for the flipped surface.
I bet that it's the same bug as the one we reported with flipped FBO.
The rendering is slow but it's expected because of the (unusual) -400 setting. It doesn't seem bogus to me (I expect the transition to start as soon as the reversed texture is displayed).
Does it looks the same without the glFinish patch?
I take for granted that the bugfix in OGLES2 will fix the flipping.

For MiniGL, it's completely off. I don't know why but it's definitely a bug in MiniGL itself and we can't really fix this except by finding the root cause which may still be because glCopyTexImage2D isn't flushing the pipeline before capturing image.
This would need an investigation with MiniGL author.

Another option possible is to comment the copyScreenshotToTexture function in engines/myst3/gfx_opengl.cpp and engines/myst3/gfx_opengl.h.
This will use a fallback mechanism (the same used by TinyGL) where image is downloaded from GPU to CPU and reuploaded as a texture. This may work better.

comment:14 by kas1e, 2 years ago

But don't you feel that at the begining it not just slow, but no effect happens, and it happens only at the end of the whole time of effect ? I mean, if we take that effect should take 100%, then it can be seen, that for about 60-70% of that time, we have "nothing" (flipped texture on ogles2, mess on minigl), and only after, in the reamining 30%, we can see necessary effect (or just part of it) ?

Maybe we just need to wait for OGLES2 to be fixed in terms of flipping, and then we can see, if it anyhow was related to and revesit issue after ?

comment:15 by kas1e, 2 years ago

@lephilousophe
Rereading everything you wrote again, and i got what you mean : you mean that while textures is flipped , no effect happens (because of that flipping bug), and once texture flips to the normal, then effect starts, but seems that texture is flipped 70% if time, and because of that we have almost no effect visibly.

Interesting through how lucky we are to catch the same issue in 3 different GL implementation, and on MiniGL and on OGLES2 and on TinyGL on MorphOS :) But we will see once OGLES2 will be fixed.

Last edited 2 years ago by kas1e (previous) (diff)

comment:16 by lephilousophe, 2 years ago

I watched again you screenshot and, as soon as the texture is flipped, I find the transitions OK. I don't think it's different on any other platform.
Don't forget that it's really slowed down and it should never be that detailed. The aim is to do something smooth, not something accurate.
If you think the flipped image begins too late, it's maybe because the implementation has to capture source image, do an offscreen render of destination image and do the transition. It's maybe not optimized in the implementation (ang glFinish may not help at all).

For the OGLES2 flipping, we can wait. If it's not fixed, we will be able to create a new minimal bug reproducer. :)

For MiniGL, after another look, it seems that Red and Green channels are switched but I couldn't find the exact swap between all colors channels.
Maybe an endianness issue due to the fact that glCopyTexImage2D stores the pixels in an unexpected fashion for the rendering later.
In our code, we never manipulate the pixels for this effect. We tell to OpenGL: capture the screen and store it in texture 1, render another scene, capture the screen and store it in texture 2. Then, render texture 1 with full opacity and render texture with a varying opacity.

comment:17 by kas1e, 2 years ago

@lephilousophe

Ok, bug in ogles2 in terms of flipping fixed! It also fix for us GRIM with enabled FBO. But, it didn't fix fliping we have there in myst3 ! It still the same. I made a video to show that on the same ogles2 library i have no issues with test case now, no issues with grim+fbo (see window is resized), but still same issues with myst3:

https://youtu.be/LqdKN3X19QI

At beginig i run test case in all possible modes, then run GRIM to show that resizable window (so FBO enabled) works too, and no issues with depth/etc, and then Myst3 showing same issue.

comment:18 by kas1e, 2 years ago

@lephilousophe

Another option possible is to comment the copyScreenshotToTexture function in engines/myst3/gfx_opengl.cpp and engines/myst3/gfx_opengl.h.

Commenting out this in both gfx_opengl.cpp and gfx_opengl_shaders.cpp and their headers make ogles2 rendering (opengl with shaders) works as expected, but missing effect on minigl.

Last edited 2 years ago by kas1e (previous) (diff)

comment:19 by kas1e, 2 years ago

@lephilousophe

Got the new beta of ogles2, with no more "flipped" texture when use glCopyTexImage2D(), and while effect kind of works there something very wrong. The effect with default transition_speed almost not visibly. While with transition_speed=0, its more or less ok, but also kind of .. small by time or something of that sort. On windows, with default transition_speed its just all fine and looks very good.

Maybe there some issues in terms of endianes when speed of transition effect is set by default ? Maybe we can somehow prinfs what value is used, so we can see what should be, and what we have. Maybe that value calculates somehow, and so on other than windows platform it acts different because of that ?

comment:20 by kas1e, 2 years ago

@lephilousophe

Added printfs and that what i have. By default (with no transition_speed option in myst3 at all), i have that when effect happens:

Drawing transition step 0/0.000000
Drawing transition step 6/0.060000
Drawing transition step 13/0.130000
Drawing transition step 20/0.200000
Drawing transition step 26/0.260000
Drawing transition step 33/0.330000
Drawing transition step 40/0.400000
Drawing transition step 46/0.460000
Drawing transition step 53/0.530000
Drawing transition step 60/0.600000
Drawing transition step 66/0.660000
Drawing transition step 73/0.730000
Drawing transition step 80/0.800000
Drawing transition step 86/0.860000
Drawing transition step 93/0.930000
Drawing transition step 100/1.000000

And i do not see effect at all, it happens too fast to notice anything.

If i add to myst3s config transition_speed=-10 (i.e. -10), then effect is visibly more or less as expected by speed (just like on win32), but in output i have instead that:

Drawing transition step 0/0.000000
Drawing transition step 3/0.030000
Drawing transition step 6/0.060000
Drawing transition step 9/0.090000
Drawing transition step 12/0.120000
Drawing transition step 15/0.150000
Drawing transition step 18/0.180000
Drawing transition step 21/0.210000
Drawing transition step 24/0.240000
Drawing transition step 27/0.270000
Drawing transition step 30/0.300000
Drawing transition step 33/0.330000
Drawing transition step 36/0.360000
Drawing transition step 39/0.390000
Drawing transition step 42/0.420000
Drawing transition step 45/0.450000
Drawing transition step 48/0.480000
Drawing transition step 51/0.510000
Drawing transition step 51/0.510000
Drawing transition step 51/0.510000
Drawing transition step 51/0.510000
Drawing transition step 51/0.510000
Drawing transition step 51/0.510000
Drawing transition step 51/0.510000
Drawing transition step 51/0.510000
Drawing transition step 54/0.540000
Drawing transition step 54/0.540000
Drawing transition step 54/0.540000
Drawing transition step 54/0.540000
Drawing transition step 54/0.540000
Drawing transition step 54/0.540000
Drawing transition step 54/0.540000
Drawing transition step 54/0.540000
Drawing transition step 54/0.540000
Drawing transition step 54/0.540000
Drawing transition step 54/0.540000
Drawing transition step 54/0.540000
Drawing transition step 57/0.570000
Drawing transition step 57/0.570000
Drawing transition step 57/0.570000
Drawing transition step 57/0.570000
Drawing transition step 57/0.570000
Drawing transition step 57/0.570000
Drawing transition step 57/0.570000
Drawing transition step 57/0.570000
Drawing transition step 57/0.570000
Drawing transition step 57/0.570000
Drawing transition step 57/0.570000
Drawing transition step 57/0.570000
Drawing transition step 57/0.570000
Drawing transition step 60/0.600000
Drawing transition step 60/0.600000
Drawing transition step 60/0.600000
Drawing transition step 60/0.600000
Drawing transition step 60/0.600000
Drawing transition step 60/0.600000
Drawing transition step 60/0.600000
Drawing transition step 60/0.600000
Drawing transition step 60/0.600000
Drawing transition step 60/0.600000
Drawing transition step 60/0.600000
Drawing transition step 60/0.600000
Drawing transition step 60/0.600000
Drawing transition step 63/0.630000
Drawing transition step 63/0.630000
Drawing transition step 63/0.630000
Drawing transition step 63/0.630000
Drawing transition step 63/0.630000
Drawing transition step 63/0.630000
Drawing transition step 63/0.630000
Drawing transition step 63/0.630000
Drawing transition step 63/0.630000
Drawing transition step 63/0.630000
Drawing transition step 63/0.630000
Drawing transition step 63/0.630000
Drawing transition step 63/0.630000
Drawing transition step 63/0.630000
Drawing transition step 66/0.660000
Drawing transition step 66/0.660000
Drawing transition step 66/0.660000
Drawing transition step 66/0.660000
Drawing transition step 66/0.660000
Drawing transition step 66/0.660000
Drawing transition step 66/0.660000
Drawing transition step 66/0.660000
Drawing transition step 66/0.660000
Drawing transition step 66/0.660000
Drawing transition step 66/0.660000
Drawing transition step 66/0.660000
Drawing transition step 66/0.660000
Drawing transition step 69/0.690000
Drawing transition step 69/0.690000
Drawing transition step 69/0.690000
Drawing transition step 69/0.690000
Drawing transition step 69/0.690000
Drawing transition step 69/0.690000
Drawing transition step 69/0.690000
Drawing transition step 69/0.690000
Drawing transition step 69/0.690000
Drawing transition step 69/0.690000
Drawing transition step 69/0.690000
Drawing transition step 69/0.690000
Drawing transition step 69/0.690000
Drawing transition step 72/0.720000
Drawing transition step 72/0.720000
Drawing transition step 72/0.720000
Drawing transition step 72/0.720000
Drawing transition step 72/0.720000
Drawing transition step 72/0.720000
Drawing transition step 72/0.720000
Drawing transition step 72/0.720000
Drawing transition step 72/0.720000
Drawing transition step 72/0.720000
Drawing transition step 72/0.720000
Drawing transition step 72/0.720000
Drawing transition step 72/0.720000
Drawing transition step 72/0.720000
Drawing transition step 75/0.750000
Drawing transition step 75/0.750000
Drawing transition step 75/0.750000
Drawing transition step 75/0.750000
Drawing transition step 75/0.750000
Drawing transition step 75/0.750000
Drawing transition step 75/0.750000
Drawing transition step 75/0.750000
Drawing transition step 75/0.750000
Drawing transition step 75/0.750000
Drawing transition step 75/0.750000
Drawing transition step 75/0.750000
Drawing transition step 78/0.780000
Drawing transition step 78/0.780000
Drawing transition step 78/0.780000
Drawing transition step 78/0.780000
Drawing transition step 78/0.780000
Drawing transition step 78/0.780000
Drawing transition step 78/0.780000
Drawing transition step 78/0.780000
Drawing transition step 78/0.780000
Drawing transition step 78/0.780000
Drawing transition step 78/0.780000
Drawing transition step 78/0.780000
Drawing transition step 78/0.780000
Drawing transition step 81/0.810000
Drawing transition step 81/0.810000
Drawing transition step 81/0.810000
Drawing transition step 81/0.810000
Drawing transition step 81/0.810000
Drawing transition step 81/0.810000
Drawing transition step 81/0.810000
Drawing transition step 81/0.810000
Drawing transition step 81/0.810000
Drawing transition step 81/0.810000
Drawing transition step 81/0.810000
Drawing transition step 81/0.810000
Drawing transition step 81/0.810000
Drawing transition step 84/0.840000
Drawing transition step 84/0.840000
Drawing transition step 84/0.840000
Drawing transition step 84/0.840000
Drawing transition step 84/0.840000
Drawing transition step 84/0.840000
Drawing transition step 84/0.840000
Drawing transition step 84/0.840000
Drawing transition step 84/0.840000
Drawing transition step 84/0.840000
Drawing transition step 84/0.840000
Drawing transition step 84/0.840000
Drawing transition step 84/0.840000
Drawing transition step 84/0.840000
Drawing transition step 87/0.870000
Drawing transition step 87/0.870000
Drawing transition step 87/0.870000
Drawing transition step 87/0.870000
Drawing transition step 87/0.870000
Drawing transition step 87/0.870000
Drawing transition step 87/0.870000
Drawing transition step 87/0.870000
Drawing transition step 87/0.870000
Drawing transition step 87/0.870000
Drawing transition step 87/0.870000
Drawing transition step 87/0.870000
Drawing transition step 87/0.870000
Drawing transition step 90/0.900000
Drawing transition step 90/0.900000
Drawing transition step 90/0.900000
Drawing transition step 90/0.900000
Drawing transition step 90/0.900000
Drawing transition step 90/0.900000
Drawing transition step 90/0.900000
Drawing transition step 90/0.900000
Drawing transition step 90/0.900000
Drawing transition step 90/0.900000
Drawing transition step 90/0.900000
Drawing transition step 90/0.900000
Drawing transition step 90/0.900000
Drawing transition step 90/0.900000
Drawing transition step 93/0.930000
Drawing transition step 93/0.930000
Drawing transition step 93/0.930000
Drawing transition step 93/0.930000
Drawing transition step 93/0.930000
Drawing transition step 93/0.930000
Drawing transition step 93/0.930000
Drawing transition step 93/0.930000
Drawing transition step 93/0.930000
Drawing transition step 93/0.930000
Drawing transition step 93/0.930000
Drawing transition step 93/0.930000
Drawing transition step 93/0.930000
Drawing transition step 96/0.960000
Drawing transition step 96/0.960000
Drawing transition step 96/0.960000
Drawing transition step 96/0.960000
Drawing transition step 96/0.960000
Drawing transition step 96/0.960000
Drawing transition step 96/0.960000
Drawing transition step 96/0.960000
Drawing transition step 96/0.960000
Drawing transition step 96/0.960000
Drawing transition step 96/0.960000
Drawing transition step 96/0.960000
Drawing transition step 96/0.960000
Drawing transition step 96/0.960000
Drawing transition step 100/1.000000
Drawing transition step 100/1.000000
Drawing transition step 100/1.000000
Drawing transition step 100/1.000000
Drawing transition step 100/1.000000
Drawing transition step 100/1.000000
Drawing transition step 100/1.000000
Drawing transition step 100/1.000000
Drawing transition step 100/1.000000
Drawing transition step 100/1.000000
Drawing transition step 100/1.000000
Drawing transition step 100/1.000000 

Not sure what all of this mean, but on win32 everything ok with default values, but for us only when i set speed to something else , but not default values.

Last edited 2 years ago by kas1e (previous) (diff)

comment:21 by kas1e, 2 years ago

@All
Ok , turns out that effect works as expected _ONLY_ when we enable VSYNC. Without enabled VSYNC we have effect working almost invisible , as it happens too fast. With VSYNC enabled all as expected. Through on win32 it seems ok with both enabled/disabled VSYNC, but at least we know to what it related.

comment:22 by aquadran, 23 months ago

Summary: Myst III Exile: missing scene transition effect on PowerPC (big-endian) machines on all OSesMYST3: missing scene transition effect on PowerPC (big-endian) machines on all OSes
Note: See TracTickets for help on using tickets.