Compare commits

...

3 Commits

Author SHA1 Message Date
riperiperi
17ba217940 Vulkan: Device map buffers written more than flushed (#4911) 2023-05-13 15:15:05 +02:00
TSRBerry
aae4595bdb Add timeout of 35 minutes to workflow jobs (#4928) 2023-05-13 13:24:43 +02:00
Mary
880fd3cfcb audio: sdl2: Do not report 5.1 if the device doesn't support it (#4908)
* amadeus: adjust VirtualDevice channel configuration reporting with HardwareDevice

* audio: sdl2: Do not report 5.1 if device doesn't support it

SDL2 5.1 to Stereo conversion is terrible and make everything sound
quiet.

Let's not expose 5.1 if not truly supported by the device.
2023-05-13 07:15:16 +00:00
9 changed files with 76 additions and 12 deletions

View File

@@ -27,6 +27,7 @@ jobs:
build:
name: ${{ matrix.OS_NAME }} (${{ matrix.configuration }})
runs-on: ${{ matrix.os }}
timeout-minutes: 35
strategy:
matrix:
os: [ubuntu-latest, macOS-latest, windows-latest]
@@ -109,6 +110,7 @@ jobs:
build_macos:
name: macOS Universal (${{ matrix.configuration }})
runs-on: ubuntu-latest
timeout-minutes: 35
strategy:
matrix:
configuration: [ Debug, Release ]
@@ -150,4 +152,4 @@ jobs:
with:
name: ava-ryujinx-${{ matrix.configuration }}-${{ env.RYUJINX_BASE_VERSION }}+${{ steps.git_short_hash.outputs.result }}-macos_universal
path: "publish_ava/*.tar.gz"
if: github.event_name == 'pull_request'
if: github.event_name == 'pull_request'

View File

@@ -12,6 +12,7 @@ concurrency: flatpak-release
jobs:
release:
timeout-minutes: 35
runs-on: ubuntu-latest
env:

View File

@@ -7,6 +7,7 @@ jobs:
pr_comment:
if: github.event.workflow_run.event == 'pull_request' && github.event.workflow_run.conclusion == 'success'
runs-on: ubuntu-latest
timeout-minutes: 35
steps:
- uses: actions/github-script@v6
with:
@@ -65,4 +66,4 @@ jobs:
} else {
core.info(`Creating a comment`);
await github.rest.issues.createComment({repo, owner, issue_number, body});
}
}

View File

@@ -46,6 +46,7 @@ jobs:
release:
name: Release ${{ matrix.OS_NAME }}
runs-on: ${{ matrix.os }}
timeout-minutes: 35
strategy:
matrix:
os: [ ubuntu-latest, windows-latest ]
@@ -143,13 +144,14 @@ jobs:
macos_release:
name: Release MacOS universal
runs-on: ubuntu-latest
timeout-minutes: 35
steps:
- uses: actions/checkout@v3
- uses: actions/setup-dotnet@v3
with:
global-json-file: global.json
- name: Setup LLVM 14
run: |
wget https://apt.llvm.org/llvm.sh
@@ -205,4 +207,4 @@ jobs:
needs: release
with:
ryujinx_version: "1.1.${{ github.run_number }}"
secrets: inherit
secrets: inherit

View File

@@ -5,6 +5,7 @@ using Ryujinx.Memory;
using Ryujinx.SDL2.Common;
using System;
using System.Collections.Concurrent;
using System.Runtime.InteropServices;
using System.Threading;
using static Ryujinx.Audio.Integration.IHardwareDeviceDriver;
@@ -18,6 +19,13 @@ namespace Ryujinx.Audio.Backends.SDL2
private readonly ManualResetEvent _pauseEvent;
private readonly ConcurrentDictionary<SDL2HardwareDeviceSession, byte> _sessions;
private bool _supportSurroundConfiguration;
// TODO: Add this to SDL2-CS
// NOTE: We use a DllImport here because of marshaling issue for spec.
[DllImport("SDL2")]
private static extern int SDL_GetDefaultAudioInfo(IntPtr name, out SDL_AudioSpec spec, int isCapture);
public SDL2HardwareDeviceDriver()
{
_updateRequiredEvent = new ManualResetEvent(false);
@@ -25,6 +33,20 @@ namespace Ryujinx.Audio.Backends.SDL2
_sessions = new ConcurrentDictionary<SDL2HardwareDeviceSession, byte>();
SDL2Driver.Instance.Initialize();
int res = SDL_GetDefaultAudioInfo(IntPtr.Zero, out var spec, 0);
if (res != 0)
{
Logger.Error?.Print(LogClass.Application,
$"SDL_GetDefaultAudioInfo failed with error \"{SDL_GetError()}\"");
_supportSurroundConfiguration = true;
}
else
{
_supportSurroundConfiguration = spec.channels == 6;
}
}
public static bool IsSupported => IsSupportedInternal();
@@ -164,6 +186,11 @@ namespace Ryujinx.Audio.Backends.SDL2
public bool SupportsChannelCount(uint channelCount)
{
if (channelCount == 6)
{
return _supportSurroundConfiguration;
}
return true;
}

View File

@@ -45,7 +45,7 @@ namespace Ryujinx.Audio.Renderer.Device
/// <param name="name">The name of the <see cref="VirtualDevice"/>.</param>
/// <param name="channelCount">The count of channels supported by the <see cref="VirtualDevice"/>.</param>
/// <param name="isExternalOutput">Indicate if the <see cref="VirtualDevice"/> is provided by an external interface.</param>
private VirtualDevice(string name, uint channelCount, bool isExternalOutput)
public VirtualDevice(string name, uint channelCount, bool isExternalOutput)
{
Name = name;
ChannelCount = channelCount;

View File

@@ -1,3 +1,4 @@
using Ryujinx.Audio.Integration;
using System.Collections.Generic;
namespace Ryujinx.Audio.Renderer.Device
@@ -22,7 +23,23 @@ namespace Ryujinx.Audio.Renderer.Device
/// The current active <see cref="VirtualDevice"/>.
/// </summary>
// TODO: make this configurable
public VirtualDevice ActiveDevice = VirtualDevice.Devices[2];
public VirtualDevice ActiveDevice { get; }
public VirtualDeviceSessionRegistry(IHardwareDeviceDriver driver)
{
uint channelCount;
if (driver.GetRealDeviceDriver().SupportsChannelCount(6))
{
channelCount = 6;
}
else
{
channelCount = 2;
}
ActiveDevice = new VirtualDevice("AudioTvOutput", channelCount, false);
}
/// <summary>
/// Get the associated <see cref="T:VirtualDeviceSession[]"/> from an AppletResourceId.

View File

@@ -56,6 +56,7 @@ namespace Ryujinx.Graphics.Vulkan
private int _writeCount;
private int _flushCount;
private int _flushTemp;
private int _lastFlushWrite = -1;
private ReaderWriterLock _flushLock;
private FenceHolder _flushFence;
@@ -200,14 +201,21 @@ namespace Ryujinx.Graphics.Vulkan
{
if (_baseType == BufferAllocationType.Auto)
{
if (_writeCount >= WriteCountThreshold || _setCount >= SetCountThreshold || _flushCount >= FlushCountThreshold)
// When flushed, wait for a bit more info to make a decision.
bool wasFlushed = _flushTemp > 0;
int multiplier = wasFlushed ? 2 : 0;
if (_writeCount >= (WriteCountThreshold << multiplier) || _setCount >= (SetCountThreshold << multiplier) || _flushCount >= (FlushCountThreshold << multiplier))
{
if (_flushCount > 0 || _flushTemp-- > 0)
{
// Buffers that flush should ideally be mapped in host address space for easy copies.
// If the buffer is large it will do better on GPU memory, as there will be more writes than data flushes (typically individual pages).
// If it is small, then it's likely most of the buffer will be flushed so we want it on host memory, as access is cached.
DesiredType = Size > DeviceLocalSizeThreshold ? BufferAllocationType.DeviceLocalMapped : BufferAllocationType.HostMapped;
bool hostMappingSensitive = _gd.Vendor == Vendor.Nvidia;
bool deviceLocalMapped = Size > DeviceLocalSizeThreshold || (wasFlushed && _writeCount > _flushCount * 10 && hostMappingSensitive) || _currentType == BufferAllocationType.DeviceLocalMapped;
DesiredType = deviceLocalMapped ? BufferAllocationType.DeviceLocalMapped : BufferAllocationType.HostMapped;
// It's harder for a buffer that is flushed to revert to another type of mapping.
if (_flushCount > 0)
@@ -215,17 +223,18 @@ namespace Ryujinx.Graphics.Vulkan
_flushTemp = 1000;
}
}
else if (_writeCount >= WriteCountThreshold)
else if (_writeCount >= (WriteCountThreshold << multiplier))
{
// Buffers that are written often should ideally be in the device local heap. (Storage buffers)
DesiredType = BufferAllocationType.DeviceLocal;
}
else if (_setCount > SetCountThreshold)
else if (_setCount > (SetCountThreshold << multiplier))
{
// Buffers that have their data set often should ideally be host mapped. (Constant buffers)
DesiredType = BufferAllocationType.HostMapped;
}
_lastFlushWrite = -1;
_flushCount = 0;
_writeCount = 0;
_setCount = 0;
@@ -418,7 +427,12 @@ namespace Ryujinx.Graphics.Vulkan
WaitForFlushFence();
_flushCount++;
if (_lastFlushWrite != _writeCount)
{
// If it's on the same page as the last flush, ignore it.
_lastFlushWrite = _writeCount;
_flushCount++;
}
Span<byte> result;

View File

@@ -261,7 +261,7 @@ namespace Ryujinx.HLE.HOS
AudioInputManager = new AudioInputManager();
AudioRendererManager = new AudioRendererManager(tickSource);
AudioRendererManager.SetVolume(Device.Configuration.AudioVolume);
AudioDeviceSessionRegistry = new VirtualDeviceSessionRegistry();
AudioDeviceSessionRegistry = new VirtualDeviceSessionRegistry(Device.AudioDeviceDriver);
IWritableEvent[] audioOutputRegisterBufferEvents = new IWritableEvent[Constants.AudioOutSessionCountMax];