protonscr

osu!stable black screens on launch using compatibility mode (DX9)

dxvkclosed d3d9
doitsujin/dxvk#4769 · opened 2025-03-14 by NelloKudo · updated 2025-06-07 · 3 comments · github
1 matching comments, n / p to jump
NNelloKudo 2025-03-14 github

As soon as osu! is launched using compatibility mode, it just black screens.
After some bisecting, I found out commit https://github.com/doitsujin/dxvk/commit/49b18f03fe7c6dd29e9aa296c5cd072d3765a1bb is breaking it, more specifically just the following lines:

// Unbind all buffers that were still bound to the backend to avoid leaks.
    EmitCs([](DxvkContext* ctx) {
      ctx->bindIndexBuffer(DxvkBufferSlice(), VK_INDEX_TYPE_UINT32);
      for (uint32_t i = 0; i < caps::MaxStreams; i++) {
        ctx->bindVertexBuffer(i, DxvkBufferSlice(), 0);
      }
    });

Steps to reproduce (osu!stable needs dotnet40 and gdiplus to work properly):

WINEPREFIX=~/.osutry winetricks -q -f dotnet20 dotnet48 gdiplus_winxp dxvk
WINEPREFIX=~/.osutry wine osu\!.exe &> logs.txt

and enable Compatibility Mode in settings.

Software information

osu! with Compatibility Mode (DX9) enabled

System information

  • GPU: RX 6600
  • Driver: mesa 25.0.1
  • Wine version: 10.3
  • DXVK version: 2.6

Log files

logs.txt

KK0bin maintainer 2025-03-14 github

Please make an Apitrace.

Wwhrvt 2025-03-14 github

FWIW copying the logic from this commit also fixes the issue, as well as reverting the first part of the original blamed commit.
(like this)

diff --git a/src/d3d9/d3d9_device.cpp b/src/d3d9/d3d9_device.cpp
index 340f6f39c..c06c14595 100644
--- a/src/d3d9/d3d9_device.cpp
+++ b/src/d3d9/d3d9_device.cpp
@@ -526,15 +526,21 @@ namespace dxvk {
       }
       return hr;
     }
+  
+    if (m_state.indices == nullptr) {
+      EmitCs([](DxvkContext* ctx) {
+        ctx->bindIndexBuffer(DxvkBufferSlice(), VK_INDEX_TYPE_UINT32);
+      });
+    }
 
-    // Unbind all buffers that were still bound to the backend to avoid leaks.
-    EmitCs([](DxvkContext* ctx) {
-      ctx->bindIndexBuffer(DxvkBufferSlice(), VK_INDEX_TYPE_UINT32);
-      for (uint32_t i = 0; i < caps::MaxStreams; i++) {
-        ctx->bindVertexBuffer(i, DxvkBufferSlice(), 0);
+    for (uint32_t i : bit::BitMask(~m_activeVertexBuffers & ((1 << 16) - 1))) {
+      if (m_state.vertexBuffers[i].vertexBuffer == nullptr) {
+        EmitCs([cIndex = i](DxvkContext* ctx) {
+          ctx->bindVertexBuffer(cIndex, DxvkBufferSlice(), 0);
+        });
       }
-    });
-
+    }
+  
     Flush();
     SynchronizeCsThread(DxvkCsThread::SynchronizeAll);
 

I have no understanding of what the code is actually doing, though.

NNelloKudo 2025-03-15 github

Here's the link to the Apitrace, sorry for not providing it earlier: ~~https://drive.google.com/file/d/1CzEKSvciamez4CAGIjnkY6zmQZR9OkKh/view?usp=sharing~~

New link (GDrive died for no reason...): https://www.dropbox.com/scl/fi/0qytrrq2d2eunwe0a3bhf/osu.trace?rlkey=v28udo0ox4dlnzrs2h3kld39v&e=1&st=wqr4n4af&dl=0

(Taken on Windows 11, on Linux it'd just fail with the game crashing, hope it isn't an issue)

Launch options