shkhln / linuxulator-steam-utils

Steam launcher for FreeBSD
MIT License
129 stars 14 forks source link

Subnautica: perf issues and no sound #67

Closed amshafer closed 2 years ago

amshafer commented 2 years ago

Findings from playing Subnautica & subnautica below zero (BZ)

If I can find a solution to the sound issue Subnautica is definitely playable. Based on the fact that the game runs despite the perf issues means it's probably a good candidate for tracing, maybe I can see what's causing the jitter. I've noticed after playing with linuxulator stuff on this system before that certain disk operations will block others, such as git diff causing youtube playback to skip a few frames.

shkhln commented 2 years ago

From options->troubleshooting: Logical Threads: 1

There is a stub for FreeBSD in dlls/ntdll/unix/system.c:

static NTSTATUS create_logical_proc_info( SYSTEM_LOGICAL_PROCESSOR_INFORMATION **data,
                                          SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX **dataex,
                                          DWORD *max_len, DWORD relation )
{
    FIXME("stub\n");
    return STATUS_NOT_IMPLEMENTED;
}

That's probably it. (Although, that doesn't necessarily have to affect performance.)

sound doesn't work I'm running virtual_oss on this machine

Sound doesn't work with virtual_oss + Wine combo in general. Someone has to debug it.

amshafer commented 2 years ago

Tried on a second computer (freebsd current instead of ghostbsd), performance is much better. Sound still isn't working, this time virtual_oss isn't involved so there might actually be something up with the game.

amshafer commented 2 years ago

As shkhln mentione on discord, this patch (his) fixed the audio. Due to AFMT_FLOAT issues:

--- dlls/wineoss.drv/mmdevdrv.c.orig    2021-07-30 22:19:29.000000000 +0300
+++ dlls/wineoss.drv/mmdevdrv.c 2021-08-08 18:09:00.610946000 +0300
@@ -22,6 +22,7 @@
 #include <stdarg.h>
 #include <errno.h>
 #include <limits.h>
+#include <stdint.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -803,6 +804,8 @@
     return 0;
 }

+#define AFMT_FLOAT AFMT_S32_LE
+
 static int get_oss_format(const WAVEFORMATEX *fmt)
 {
     WAVEFORMATEXTENSIBLE *fmtex = (WAVEFORMATEXTENSIBLE*)fmt;
@@ -1407,6 +1410,22 @@
         memset(buffer, 0, frames * This->fmt->nBlockAlign);
 }

+static void float_to_int(unsigned char* buf, int count) {
+
+    int i; float x;
+
+    for (i = 0; i < count; i += 4) {
+
+        x = *(float*)(buf + i);
+
+        x = x * 2147483648;
+        if (x > INT32_MAX) { x = INT32_MAX; }
+        if (x < INT32_MIN) { x = INT32_MIN; }
+
+        *(int32_t*)(buf + i) = x;
+    }
+}
+
 static void oss_write_data(ACImpl *This)
 {
     ssize_t written_bytes;
@@ -1481,6 +1500,8 @@
     if(This->session->mute)
         silence_buffer(This, buf, to_write_frames);

+    float_to_int(buf, to_write_bytes);
+
     written_bytes = write(This->fd, buf, to_write_bytes);
     if(written_bytes < 0){
         /* EAGAIN is OSS buffer full, log that too */
@@ -1506,6 +1527,8 @@
             silence_buffer(This, This->local_buffer, to_write_frames);

         TRACE("wrapping to write %lu frames from beginning\n", to_write_frames);
+
+        float_to_int(This->local_buffer, to_write_bytes);

         written_bytes = write(This->fd, This->local_buffer, to_write_bytes);
         if(written_bytes < 0){