finalburnneo / FBNeo

FinalBurn Neo - We are Team FBNeo.
http://neo-source.com
Other
940 stars 368 forks source link

Flickering with cv1000 games on Apple Silicon M1 #1129

Closed darksaviorx closed 1 year ago

darksaviorx commented 2 years ago

Retroarch 1.10.3 (metal/universal version) with FinalBurn Neo v1.0.0.03 d6459f6c. Stock settings but I set up my joystick. Mac OS Monterey 12.5.

It happens on my 1440p 144Hz monitor and 4k 60hz tv. I tested akatana and dsmbl. To make sure the flickering only happens on cv1000 games, I tried a cps3 game and a system32 game and they have no issues.

After my tests I did try to fiddle with vsync and other video settings I can't recall at the moment but it didn't change anything.

retroarch2022_07_3102_28_33.log

barbudreadmon commented 2 years ago

Can you share a video or something ? Does it happen with standalone macos builds ?

darksaviorx commented 2 years ago

https://www.youtube.com/watch?v=1FA5Ws5Fgug The last standalone macos build is from 2021 which has no cv1000 support. There are no nightlies for macos.

barbudreadmon commented 2 years ago

that's likely to be a blitter threading issue specific to macos.

@0xe1f are there more up-to-date standalone builds somewhere ? is there a guide on building fbneo for macos ? does this issue happen on your side ?

barbudreadmon commented 2 years ago

@darksaviorx can you try disabling blitter threading in dips ?

darksaviorx commented 2 years ago

I disabled the thread blitter, restarted retroarch and there was no change. I forgot to also say that retroarch crashes if I exit after playing a cv1000 game. No crash if I exit a non-cv1000 game. crash when exiting.txt

barbudreadmon commented 2 years ago

retroarch crashes if I exit after playing a cv1000 game

afaik retroarch won't save core options if it crashes at exit, so are you sure the dips is properly disabled ? From your logs, it looks to me like you are still using the threaded blitter

darksaviorx commented 2 years ago

I save the settings manually. After restarting retroarch it's showing me the thread blitter as disabled. I also checked my akatana.opt and it says fbneo-dipswitch-akatana-Thread_Blitter = "Off"

dinkc64 commented 2 years ago

Wow, that sucks - sorry about this problem, though we've never tried it on a mac yet.
At first it looks like a bug in the threading, but you have threading disabled. hrmf.. Memory corruption maybe? I think the only way we'd be able to fix this is if you could build the core with address sanitizer and ubsan. barbudreadmon might be able to give you some tips to compile the core on your side with those options.

best regards,

darksaviorx commented 2 years ago

I just wanted to play a quick game of Akai Katana lol. The alternative is not practical but it works...Parallels running Win11 arm64 vm running Retroarch X86 DX11.

barbudreadmon commented 2 years ago

I don't know how to use asan on macos, i see there are instructions at https://developer.apple.com/documentation/xcode/diagnosing-memory-thread-and-crash-issues-early but they don't seem very clear, and i don't even know what compiler you are supposed to use.

I did another asan check on my side and couldn't find anything, i also looked for potential problem code for arm/aarch64 and didn't find either, but since it run on pi4 i doubt that could be an arm/aarch64 issue. I guess it's an apple compiler bug, and without an apple dev i doubt we'll get anywhere.

cjom commented 2 years ago

Allow me to enter the conversation just to say I have compiled today for MacOS and you can get it in https://github.com/cjom/FBNeo/releases/latest

It was compiled using workflow based in this https://github.com/finalburnneo/FBNeo/blob/master/.github/workflows/macos.yml.ignore but I don't have how to test if it works.

The purpose of my testing build is to test the new controller mapping functions, but you can use it to check cv1000 issue. An if possible to give some feedback about the ingame mapping menus, that would be great ;)

darksaviorx commented 2 years ago

I don't know how to execute the contents of that zip file so I put the contents into the existing fbn.app. I'm not sure if that's caused any issues but the games load to a black screen.

dinkc64 commented 2 years ago

cjom, awesome - any thing you can do to help out will be super appreciated! :)

barbudreadmon commented 2 years ago

@darksaviorx those games didn't previously worked ? they did this from the first time you launched them ? i'm only thinking about this now but there were issues with the eeprom/savestate code in cv1k not so long ago, so older saves aren't guaranteed to work and might even cause memory corruption.

darksaviorx commented 2 years ago

@barbudreadmon For retroarch? They always have flickering. I wipe the retroarch folder it creates to make sure I'm not using old configs. This is a clean install.

cjom commented 2 years ago

@darksaviorx from what I understand looking at the code, this has to be run from terminal.

You should extract the zip content into /Applications (but that requires administrator password) or ~/Applications (a folder in user space).

Probably you also should change the name of extracted folder from "Contents" to "FBNeo" (maybe?) and I don't know if, like in linux, you'll need to give executable permission to the file "MacOS/FinalBurn Neo".

(edited to make more clear:) Finally you need to run the app in a terminal window passing to it the path where the roms are and what game you want to play, something similar to: "FinalBurn Neo" "~/FolderWithROMs" sfiii

darksaviorx commented 2 years ago

@cjom FBN won't open. Crashes. "sparkle.framework" is damaged and can't be opened. You should move it to the Trash." dyld[69362]: Library not loaded: '@rpath/Sparkle.framework/Versions/A/Sparkle' Referenced from: '/Applications/FBN/Contents/MacOS/FinalBurn Neo' Reason: tried: '/Applications/FBN/Contents/MacOS/../Frameworks/Sparkle.framework/Versions/A/Sparkle' (code signature in <1AAA2191-6EA6-35D4-BA37-24C404CE4C29> '/Applications/FBN/Contents/Frameworks/Sparkle.framework/Versions/A/Sparkle' not valid for use in process: library load disallowed by system policy), '/Applications/FBN/Contents/MacOS/../Frameworks/Sparkle.framework/Versions/A/Sparkle' (code signature in <1AAA2191-6EA6-35D4-BA37-24C404CE4C29> '/Applications/FBN/Contents/Frameworks/Sparkle.framework/Versions/A/Sparkle' not valid for use in process: library load disallowed by system policy), '/Library/Frameworks/Sparkle.framework/Versions/A/Sparkle' (no such file), '/System/Library/Frameworks/Sparkle.framework/Versions/A/Sparkle' (no such file) zsh: abort ./FinalBurn\ Neo

If I replace the frameworks folder with the one that comes with FBN 1.0.0.2 then it loads but once again the games load to a black screen.

0xe1f commented 2 years ago

@barbudreadmon haven't tried the retroarch version on macOS, and I don't yet have a silicon mac to test, sorry :/

cjom commented 2 years ago

I see the issue here is "library load disallowed by system policy". I have zero experience in mac, but I found a post about a similar problem that pointed to https://support.apple.com/en-us/HT202491

where they show a way to temporarily allow any app to run, if you are willing to try...

0xe1f commented 2 years ago

I had to pay for a dev membership and sign all builds to get them to validate. if you're trying to distribute builds, you'll likely need to do the same.

dinkc64 commented 2 years ago

0xe1f, as you can see we're in dire needs of a mac dev to help - is there any chance you could try running fbn w/ the cv1k games and see what's causing the crasher? The real problem is when the fbn libretro core is ran under retroarch w/ romset akatana, perhaps you could try this in your build of fbn with asan and ubsan if possible? :) All I need is the logs from ubsan and asan (address sanitizer) - then I can locate and fix the problem.

best regards,

0xe1f commented 2 years ago

My weekdays have been very busy lately, but let's try something this weekend :)

barbudreadmon commented 2 years ago

@0xe1f checking if the issue is reproducible on mac standalone x86 would be a great start :)

darksaviorx commented 2 years ago

@dinkc64 I'm using akatana because that's what I was intending on playing but I also loaded dsmbl to make sure it happens on all cv1000 games.

Btw, I just tried Retroarch x86_x64 FBN on my Macbook Air 2012 with Catalina and the cv1000 games also flicker on it.

dinkc64 commented 2 years ago

darksaviorx, thanks for confirming

0xe1f commented 2 years ago

I tried loading mmpork and dsmbl in the Mac standalone. Loading seems fine:

  Loading program (u4)...
  Loading program (u2)...
  Loading sound (u23)...
  Loading sound (u24)...
  Initialization successful

However, I don't get any video - the screen is black:

Screen Shot 2022-08-06 at 22 12 08

This was on an x86 mac, using standalone mac version. Other games load fine.

And pressing buttons doesn't seem to do anything. I'll take a look at it when I get some time.

dinkc64 commented 2 years ago

0xe1f, how many fps it's getting while displaying the black screen? If it's very low, it could take a while. (the games are quite demanding, needing a full 2ghz at times) If still nothing, try DIPs -> Thread Blitter -> Off.

barbudreadmon commented 1 year ago

The issue might be fixed, testers welcome.

dinkc64 commented 1 year ago

it would be nice if fixed, but, i doubt it unless the compiler is really stupid.

barbudreadmon commented 1 year ago

msvc2022 was having a black screen before this change, which might be the same issue @0xe1f had on non-arm apple device. my guess is that those compilers aren't smart indeed

taoenwen commented 1 year ago

image

@dinkc64 Debugging found that a lot of time was consumed in each frame of the session, thus falling into a black screen

dinkc64 commented 1 year ago

taoenwen, barbudreadmon, thanks for the info

barbudreadmon commented 1 year ago

It doesn't seem it helped with the flickering issue on apple arm, some user is (still) having that same issue on iphone.

From the black screen issue, i think those compilers might have issues when the one definition rule is not followed, so maybe another declaration is at fault (rectangle ?).

yoyofr commented 1 year ago

Hi, I've just started to play with retroarch & fbn on my M1 mac & ipad. I'm pretty sure it's related to thready.h. When I remove thready and do manual call to gfx_exec() it works well. I will analyze in more details

barbudreadmon commented 1 year ago

Hmmmm @darksaviorx said the issue was happening even with threading disabled though ?

yoyofr commented 1 year ago

To disable it using the flag is not enough, it might be an issue with pthread (or rather semaphore) usage in macos. I forced no thread by changing the define in thready.h and it works well (no issue with gfx & no crash at exit):

if !defined(WIN32) && ( defined(linux) || defined(ANDROID) || defined(APPLE) )

//#define THREADY THREADY_PTHREAD

define THREADY THREADY_0THREAD

include

include

include

endif

yoyofr commented 1 year ago

I was able to confirm the issue: osx doesn't support unnamed semaphore -> sem_init is doing nothing.

you have to use named semaphore, basically replace sem_init by sem_open & sem_destroy by sem_close & sem_unlink https://medium.com/helderco/semaphores-in-mac-os-x-fd7a7418e13b

I tested and it works well.

yoyofr commented 1 year ago

struct threadystruct { INT32 thready_ok; INT32 ok_to_thread; INT32 ok_to_wait; INT32 end_thread; sem_t our_event; sem_t wait_event; pthread_t our_thread; void (*our_callback)(); INT32 startup_frame;

void init(void (*thread_callback)()) {
    thready_ok = 0;
    ok_to_thread = 0;
    ok_to_wait = 0;
    end_thread = 0;

    our_callback = thread_callback;

    INT32 our_thread_rv = pthread_create(&our_thread, NULL, ThreadyProc, NULL);

    INT32 our_event_rv;// = sem_init(&our_event, 0, 0); //sem_init not supported in OSX
    if ((our_event = sem_open("/sem_our_event",O_CREAT, 0644, 1))==SEM_FAILED) {
        our_event_rv=-1;
    } else our_event_rv=0;

    INT32 wait_event_rv;// = sem_init(&wait_event, 0, 0);  //sem_init not supported in OSX
    if ((wait_event = sem_open("/sem_wait_event",O_CREAT, 0644, 1))==SEM_FAILED) {
        wait_event_rv=-1;
    } else wait_event_rv=0;

    if (our_thread_rv == 0 && wait_event_rv == 0 && our_event_rv == 0) {
        bprintf(0, _T("Thready: we're gonna git 'r dun!\n"));
        thready_ok = 1;
        ok_to_thread = 1;
    } else {
        bprintf(0, _T("Thready: failure to create thread - falling back to single-thread mode!\n"));
    }
}

void exit() {
    if (thready_ok) {
        //bprintf(0, _T("Thready: notify thread to exit..\n"));
        end_thread = 1;
        sem_post(our_event);
        do {
            sleep(0.10); // let thread realize it's time to die
        } while (~end_thread & 0x100);
        pthread_join(our_thread, NULL);

        //sem_destroy not support in OSX
        //sem_destroy(&our_event);
        //sem_destroy(&wait_event);
        sem_close(our_event);
        sem_unlink("/sem_our_event");
        sem_close(wait_event);
        sem_unlink("/sem_wait_event");

        thready_ok = 0;
    }
}

void scan() {
    SCAN_VAR(startup_frame);
}

void reset() {
    startup_frame = STARTUP_FRAMES;
}

void set_threading(INT32 value)
{
    ok_to_thread = value;
}

void notify() {
    if (startup_frame > 0) {
        // run in synchronous mode for startup_frame frames
        startup_frame--;
        our_callback();
        return;
    }
    if (thready_ok && ok_to_thread) {
        sem_post(our_event);
        ok_to_wait = 1;
    } else {
        // fallback to single-threaded mode
        our_callback();
    }
}
void notify_wait() {
    if (ok_to_wait) {
        sem_wait(wait_event);
        ok_to_wait = 0;
    }
}

};

static threadystruct thready;

static void ThreadyProc(void) { do { sem_wait(thready.our_event);

    if (thready.end_thread == 0) {
        thready.our_callback();
        sem_post(thready.wait_event);
    } else {
        sem_post(thready.wait_event);
        thready.end_thread |= 0x100;
        bprintf(0, _T("Thready: thread-event thread ending..\n"));
        return 0;
    }
} while (1);

return 0;

}

endif // THREADY_PTHREAD

dinkc64 commented 1 year ago

yoyofr, thank you for the fix!! Later tonight I will do some tests tonight to make sure all is well with other systems, and also make sure to create a different named semaphore to avoid conflicts if more than 1 fbn is open (or so), then commit it.

best regards,

yoyofr commented 1 year ago

OK thanks. You can probably add the pid to the semaphore names with a call to getpid().

dinkc64 commented 1 year ago

@yoyofr, great idea :) Please test this attached thready.h: thready.zip

dinkc64 commented 1 year ago

I had to separate the apple version (named sem) from regular pthreads version (unnamed sem). It's funny, as apple won't support unnamed semaphores, windows pthreads won't support named semaphores - therefore I couldn't test it.

best regards,

barbudreadmon commented 1 year ago

I tested this on linux, #include <fcntl.h> was required for O_CREAT but aside from that it seemed to work. Performance seemed about the same as unnamed sem too.

dinkc64 commented 1 year ago

yoyofr, barbudreadmon, I wonder if apple also needs fcntl.h included?
best regards,

yoyofr commented 1 year ago

Will check tonight (CET timezone)

dinkc64 commented 1 year ago

I will commit it for now, because a friend also wants to test it after the bot compiles it

dinkc64 commented 1 year ago

thanks :)

dinkc64 commented 1 year ago

@barbudreadmon please transfer it over? :)

barbudreadmon commented 1 year ago

sure, done :)

yoyofr commented 1 year ago

I've just tried the new thready.h and it works well on mac m1. Also tried to compile without fcntl.h and it is also ok, so not required on apple.