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

fix(ddprobe): verifying frames should test up to 10 frames #3414

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

Nonary
Copy link
Collaborator

@Nonary Nonary commented Nov 22, 2024

Description

Fixed a bug that caused the verify frame code to exit the loop early if it failed to acquire a frame (due to timeouts or other reasons).

It should now properly try up to 10 times.

Issues Fixed or Closed

N/A

Type of Change

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Dependency update (updates to dependencies)
  • Documentation update (changes to documentation)
  • Repository update (changes to repository files, e.g. .github/...)

Checklist

  • My code follows the style guidelines of this project
  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have added or updated the in code docstring/documentation-blocks for new or existing methods/components

Fixed a bug that caused the verify frame code to exit the loop early if it failed to aquire a frame (due to timeouts or other reasons).

It should now properly try up to 10 times.
Copy link

codecov bot commented Nov 22, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 11.12%. Comparing base (d5854ae) to head (4260b52).

Additional details and impacted files
@@            Coverage Diff             @@
##           master    #3414      +/-   ##
==========================================
- Coverage   11.13%   11.12%   -0.01%     
==========================================
  Files          99       99              
  Lines       17253    17253              
  Branches     8045     8045              
==========================================
- Hits         1921     1920       -1     
  Misses      12639    12639              
- Partials     2693     2694       +1     
Flag Coverage Δ
Linux 8.37% <ø> (ø)
Windows 5.31% <ø> (ø)
macOS-13 13.62% <ø> (-0.02%) ⬇️
macOS-14 12.65% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

see 1 file with indirect coverage changes

---- 🚨 Try these New Features:

@ReenigneArcher ReenigneArcher changed the title bugfix: verifying frames should test up to 10 frames fix(ddprobe): verifying frames should test up to 10 frames Nov 22, 2024
@Nonary Nonary marked this pull request as ready for review November 23, 2024 02:09
@cgutman
Copy link
Collaborator

cgutman commented Nov 26, 2024

Does this mean in the worst case we're potentially waiting 5 seconds (500 ms * 10 tries) per invocation of ddprobe? That seems bad.

It already takes quite a while (like 30 seconds or so) to reprobe decoders when a display isn't connected due to ddprobe running over and over.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot wasn't able to review any files in this pull request.

Files not reviewed (1)
  • tools/ddprobe.cpp: Language not supported
@FrogTheFrog
Copy link
Collaborator

FrogTheFrog commented Dec 27, 2024

I was looking into this ddprobe issue a little and am wondering if we could cheat a little.

According to MS (https://learn.microsoft.com/en-us/windows/win32/api/dxgi1_6/ne-dxgi1_6-dxgi_gpu_preference) there are only 3 possible values for GPU preference. If we discard the first one, it's 2 - 1 and 2.

We could then (I know it's not nice, but it's a solution) copy ddprobe.exe to get ddprobe_1.exe and ddprobe_2.exe and run them in parallel. Then in the worst case scenario the validate_and_test_gpu_preference would take 5 secs.

We could further uglify this by also running verify_frame_capture variants in parallel, so the whole probe_for_gpu_preference would take 5 secs in the worst case scenario.

@RebelliousX
Copy link

RebelliousX commented Jan 4, 2025

I was looking into this ddprobe issue a little and am wondering if we could cheat a little.

According to MS (https://learn.microsoft.com/en-us/windows/win32/api/dxgi1_6/ne-dxgi1_6-dxgi_gpu_preference) there are only 3 possible values for GPU preference. If we discard the first one, it's 2 - 1 and 2.

We could then (I know it's not nice, but it's a solution) copy ddprobe.exe to get ddprobe_1.exe and ddprobe_2.exe and run them in parallel. Then in the worst case scenario the validate_and_test_gpu_preference would take 5 secs.

We could further uglify this by also running verify_frame_capture variants in parallel, so the whole probe_for_gpu_preference would take 5 secs in the worst case scenario.

Just to follow up on this, as we discussed in #3441 you mentioned that this PR might fix or attempt to fix the issue we went through. I tried this PR's ddprobe.exe and replaced it with your PR build of sunshine. And still can't connect to the VDD or find a suitable encoder. I am mentioning this here just to let you know that this PR doesn't fix the issue contrary to what you thought it would. (the comment is marked as off-topic / outdated).

Here is a log of this PR's ddprobe.exe combined with your build of sunshine from your PR.

Sunshine log
[2025-01-03 21:58:44.569]: Info: Sunshine version: 0.0.0.ab23da8c10a4b5ce36a8f05287b6bbbf3f118fd1
[2025-01-03 21:58:44.570]: Info: Package Publisher: LizardByte
[2025-01-03 21:58:44.570]: Info: Publisher Website: https://app.lizardbyte.dev
[2025-01-03 21:58:44.570]: Info: Get support: https://app.lizardbyte.dev/support
[2025-01-03 21:58:44.570]: Info: Provided workaround settings for SettingsManager:
{
  "hdr_blank_delay": null
}
[2025-01-03 21:58:44.576]: Info: Currently available display devices:
[
  {
    "device_id": "{7c0d6921-fd7a-5acb-92d9-e9e5cfea32f1}",
    "display_name": "\\\\.\\DISPLAY1",
    "friendly_name": "",
    "info": {
      "hdr_state": null,
      "origin_point": {
        "x": 0,
        "y": 0
      },
      "primary": true,
      "refresh_rate": {
        "type": "rational",
        "value": {
          "denominator": 2310880,
          "numerator": 138700000
        }
      },
      "resolution": {
        "height": 1080,
        "width": 1920
      },
      "resolution_scale": {
        "type": "rational",
        "value": {
          "denominator": 100,
          "numerator": 125
        }
      }
    }
  },
  {
    "device_id": "{9acddf6d-43cc-576e-9aff-0c5fc80b4cc8}",
    "display_name": "",
    "friendly_name": "VDD by MTT",
    "info": null
  }
]
[2025-01-03 21:58:45.027]: Info: nvprefs: No need to modify application profile settings
[2025-01-03 21:58:45.027]: Info: nvprefs: Changed OGL_CPL_PREFER_DXPRESENT to OGL_CPL_PREFER_DXPRESENT_PREFER_ENABLED for base profile
[2025-01-03 21:58:45.097]: Info: Compiling shaders...
[2025-01-03 21:58:45.138]: Warning: include/base_vs.hlsl(28,13-36): warning X3556: integer modulus may be much slower, try using uints if possible.
[2025-01-03 21:58:45.155]: Info: System tray created
[2025-01-03 21:58:45.184]: Warning: include/base_vs.hlsl(28,13-36): warning X3556: integer modulus may be much slower, try using uints if possible.
[2025-01-03 21:58:45.213]: Warning: include/base_vs.hlsl(28,13-36): warning X3556: integer modulus may be much slower, try using uints if possible.
[2025-01-03 21:58:45.232]: Warning: include/base_vs.hlsl(28,13-36): warning X3556: integer modulus may be much slower, try using uints if possible.
[2025-01-03 21:58:45.283]: Warning: include/base_vs.hlsl(28,13-36): warning X3556: integer modulus may be much slower, try using uints if possible.
[2025-01-03 21:58:45.295]: Warning: include/base_vs.hlsl(28,13-36): warning X3556: integer modulus may be much slower, try using uints if possible.
[2025-01-03 21:58:45.295]: Info: Compiled shaders
[2025-01-03 21:58:45.307]: Info: Trying encoder [quicksync]
[2025-01-03 21:58:45.445]: Info: ddprobe.exe 1  --verify-frame-capture returned 0x00000000
[2025-01-03 21:58:45.445]: Info: Set GPU preference: 1
[2025-01-03 21:58:45.958]: Error: Failed to locate an output device
[2025-01-03 21:58:46.689]: Error: Failed to locate an output device
[2025-01-03 21:58:46.891]: Info: Encoder [quicksync] failed
[2025-01-03 21:58:46.892]: Error: Couldn't find any working encoder matching [quicksync]
[2025-01-03 21:58:46.892]: Info: // Testing for available encoders, this may generate errors. You can safely ignore those errors. //
[2025-01-03 21:58:46.893]: Info: Trying encoder [nvenc]
[2025-01-03 21:58:47.409]: Error: Failed to locate an output device
[2025-01-03 21:58:48.135]: Error: Failed to locate an output device
[2025-01-03 21:58:48.349]: Info: Encoder [nvenc] failed
[2025-01-03 21:58:48.352]: Info: Trying encoder [amdvce]
[2025-01-03 21:58:48.862]: Error: Failed to locate an output device
[2025-01-03 21:58:49.577]: Error: Failed to locate an output device
[2025-01-03 21:58:49.778]: Info: Encoder [amdvce] failed
[2025-01-03 21:58:49.781]: Info: Trying encoder [software]
[2025-01-03 21:58:50.294]: Error: Failed to locate an output device
[2025-01-03 21:58:51.024]: Error: Failed to locate an output device
[2025-01-03 21:58:51.225]: Info: Encoder [software] failed
[2025-01-03 21:58:51.225]: Error: Couldn't find any working encoder that meets HEVC/AV1 requirements
[2025-01-03 21:58:51.226]: Fatal: Unable to find display or encoder during startup.
[2025-01-03 21:58:51.226]: Fatal: Please ensure your manually chosen GPU and monitor are connected and powered on.
[2025-01-03 21:58:51.226]: Error: Video failed to find working encoder
[2025-01-03 21:58:51.235]: Info: Configuration UI available at [https://localhost:47990]
[2025-01-03 21:58:52.024]: Info: Registered Sunshine mDNS service
[2025-01-03 21:58:54.078]: Info: Trying to apply display device settings. API is available: true
[2025-01-03 21:58:54.078]: Info: Using the following configuration:
{
  "device_id": "{9acddf6d-43cc-576e-9aff-0c5fc80b4cc8}",
  "device_prep": "EnsureOnlyDisplay",
  "hdr_state": "Disabled",
  "refresh_rate": {
    "type": "rational",
    "value": {
      "denominator": 1,
      "numerator": 60
    }
  },
  "resolution": {
    "height": 1080,
    "width": 1920
  }
}
[2025-01-03 21:58:54.079]: Info: Active topology before any changes:
[
  [
    "{7c0d6921-fd7a-5acb-92d9-e9e5cfea32f1}"
  ]
]
[2025-01-03 21:58:54.082]: Info: Currently available devices:
[
  {
    "device_id": "{7c0d6921-fd7a-5acb-92d9-e9e5cfea32f1}",
    "display_name": "\\\\.\\DISPLAY1",
    "friendly_name": "",
    "info": {
      "hdr_state": null,
      "origin_point": {
        "x": 0,
        "y": 0
      },
      "primary": true,
      "refresh_rate": {
        "type": "rational",
        "value": {
          "denominator": 2310880,
          "numerator": 138700000
        }
      },
      "resolution": {
        "height": 1080,
        "width": 1920
      },
      "resolution_scale": {
        "type": "rational",
        "value": {
          "denominator": 100,
          "numerator": 125
        }
      }
    }
  },
  {
    "device_id": "{9acddf6d-43cc-576e-9aff-0c5fc80b4cc8}",
    "display_name": "",
    "friendly_name": "VDD by MTT",
    "info": null
  }
]
[2025-01-03 21:58:54.082]: Info: Will compute new display device topology from the following input:
  - initial topology: [["{7c0d6921-fd7a-5acb-92d9-e9e5cfea32f1}"]]
  - initial primary devices: ["{7c0d6921-fd7a-5acb-92d9-e9e5cfea32f1}"]
  - configuring unspecified device: false
  - device to configure: "{9acddf6d-43cc-576e-9aff-0c5fc80b4cc8}"
  - additional devices to configure: []
[2025-01-03 21:58:54.082]: Info: Newly computed display device topology data:
  - topology: [["{9acddf6d-43cc-576e-9aff-0c5fc80b4cc8}"]]
  - change is needed: true
  - additional devices to configure: []
[2025-01-03 21:58:54.655]: Info: Changing display modes to:
{
  "{9acddf6d-43cc-576e-9aff-0c5fc80b4cc8}": {
    "refresh_rate": {
      "denominator": 1,
      "numerator": 60
    },
    "resolution": {
      "height": 1080,
      "width": 1920
    }
  }
}
[2025-01-03 21:58:55.057]: Info: Changing HDR states to:
{
  "{9acddf6d-43cc-576e-9aff-0c5fc80b4cc8}": "Disabled"
}
[2025-01-03 21:58:55.475]: Info: Trying encoder [quicksync]
[2025-01-03 21:58:56.002]: Error: Failed to locate an output device
[2025-01-03 21:58:56.733]: Error: Failed to locate an output device
[2025-01-03 21:58:56.933]: Info: Encoder [quicksync] failed
[2025-01-03 21:58:56.934]: Error: Couldn't find any working encoder matching [quicksync]
[2025-01-03 21:58:56.934]: Info: // Testing for available encoders, this may generate errors. You can safely ignore those errors. //
[2025-01-03 21:58:56.936]: Info: Trying encoder [nvenc]
[2025-01-03 21:58:57.452]: Error: Failed to locate an output device
[2025-01-03 21:58:58.180]: Error: Failed to locate an output device
[2025-01-03 21:58:58.391]: Info: Encoder [nvenc] failed
[2025-01-03 21:58:58.392]: Info: Trying encoder [amdvce]
[2025-01-03 21:58:58.904]: Error: Failed to locate an output device
[2025-01-03 21:58:59.621]: Error: Failed to locate an output device
[2025-01-03 21:58:59.823]: Info: Encoder [amdvce] failed
[2025-01-03 21:58:59.825]: Info: Trying encoder [software]
[2025-01-03 21:59:00.342]: Error: Failed to locate an output device
[2025-01-03 21:59:01.058]: Error: Failed to locate an output device
[2025-01-03 21:59:01.261]: Info: Encoder [software] failed
[2025-01-03 21:59:01.261]: Error: Couldn't find any working encoder that meets HEVC/AV1 requirements
[2025-01-03 21:59:01.261]: Fatal: Unable to find display or encoder during startup.
[2025-01-03 21:59:01.262]: Fatal: Please ensure your manually chosen GPU and monitor are connected and powered on.
[2025-01-03 21:59:04.285]: Info: Trying to revert applied display device settings. API is available: true
[2025-01-03 21:59:04.287]: Info: Trying to change back the HDR states to:
{
  "{9acddf6d-43cc-576e-9aff-0c5fc80b4cc8}": "Enabled"
}
[2025-01-03 21:59:04.370]: Info: Trying to change back the display modes to:
{
  "{9acddf6d-43cc-576e-9aff-0c5fc80b4cc8}": {
    "refresh_rate": {
      "denominator": 1,
      "numerator": 165
    },
    "resolution": {
      "height": 1080,
      "width": 1920
    }
  }
}

@cgutman
Copy link
Collaborator

cgutman commented Jan 8, 2025

According to MS (https://learn.microsoft.com/en-us/windows/win32/api/dxgi1_6/ne-dxgi1_6-dxgi_gpu_preference) there are only 3 possible values for GPU preference. If we discard the first one, it's 2 - 1 and 2.

The registry values don't actually correspond to the values in DXGI_GPU_PREFERENCE, even though they superficially look like they do. When you look at UI in Settings, it will try to classify the GPUs into low-power and high-performance, but there's actually no limit to only having a single GPU from either type.

If you do something like run a 3 GPU setup (ex: iGPU + 2 dGPUs), the valid values will be:

  1. iGPU
  2. dGPU 1
  3. dGPU 2

@FrogTheFrog
Copy link
Collaborator

If you do something like run a 3 GPU setup (ex: iGPU + 2 dGPUs), the valid values will be:
1. iGPU
2. dGPU 1
3. dGPU 2

Whatever the case is, the current solution from this branch does not seem to work for @RebelliousX. I have made him a special ddprobe that only returns true on value 2.

What if we allow this GPU preference to be also user-configurable? Newest VDD by MikeTheTech also allows to specify which GPU should be used, so maybe a preference with value 0 would also work out of the box? I do not have a hybrid nor another GPU to test this though.

With that said, I would propose to add a new parameter with the following values (at least until ddprobe is fixed):

  • -1 - use ddprobe (default)
  • 0 or more - use whatever user wants

@ReenigneArcher
Copy link
Member

What if we allow this GPU preference to be also user-configurable?

Sounds reasonable to me.

@cgutman
Copy link
Collaborator

cgutman commented Jan 10, 2025

@FrogTheFrog The problem happening in #3521 (comment) is that the display topology that ddprobe.exe executed under initially is not the topology that will be used while streaming. When running initially, ddprobe.exe determines that the primary display is attached to the iGPU, so it configured Sunshine to use that. Later on when Sunshine updates the display topology during streaming initialization to a (virtual) display attached to a secondary GPU, it's bound to the wrong GPU and so DXGI capture fails.

Unfortunately the binding of a process to a GPU is permanent (unless we could do something clever/nasty like unloading DXGI.dll). I haven't looked into your display reconfiguration code, but if you know ahead of time that the display you will be configuring is virtual, I think we could try to opt for the OS default GPU (0) rather than probing and probably getting it wrong.

@RebelliousX
Copy link

I haven't looked into your display reconfiguration code, but if you know ahead of time that the display you will be configuring is virtual, I think we could try to opt for the OS default GPU (0) rather than probing and probably getting it wrong.

For me, when I set it to 0, it worked on both GPUs the iGPU and dGPU and I didn't have to even fill in the Adapter Name. If I put the UUID for the monitor (in my case, the virtual one attached to dGPU), the right GPU is chosen. If I leave the device ID for the monitor empty, the iGPU is chosen for the main physical display. -1 is defaulting to 1 and that forces the iGPU to be selected. 2 works for the dGPU but not the iGPU on main display. I mentioned this in #3521 but understandably @ReenigneArcher wanted to be safe and set it as current behavior lest it cause problems.

@cgutman
Copy link
Collaborator

cgutman commented Jan 10, 2025

Interesting, I suppose it's possible that 24H2 changed behavior here because DXGI capture definitely didn't work across GPUs before without determining the correct GPU ahead of time. That's the reason we had to write all this probing code in the first place.

@FrogTheFrog
Copy link
Collaborator

Its not trivial to detect whether the display is virtual or not. There is an enum that could be set accordingly by the driver itself somehow to indicate that it's a virtual display, but so far I have not seen any of the popular VDDs doing that. Instead thay say that it's a HDMI display.

In the new VDD release, you can select which GPU shall be used by it. I don't know what it does exactly, but maybe it effects the enumeration somehow.

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

Successfully merging this pull request may close these issues.

5 participants