Compare commits

...

14 Commits

Author SHA1 Message Date
Ac_K
e6700b314f lbl: Migrate service to Horizon (#5628)
* lbl: Migrate service to Horizon

* Fix formatting

* Addresses gdkchan's feedback

* Fix comments
2023-09-14 09:50:19 +02:00
gdkchan
e2cfe6fe44 Fix shader GlobalToStorage pass when base address comes from local or shared memory (#5668)
* Fix shader GlobalToStorage pass when base address comes from local or shared memory

* Shader cache version bump
2023-09-11 01:22:18 +00:00
Marco Carvalho
210f475484 Replacing 'Assembly.GetExecutingAssembly()' with 'Type.Assembly' (#5545) 2023-09-07 14:10:58 +02:00
gdkchan
ddb6493896 Delete ResourceAccess (#5626)
* Delete ResourceAccess

* Set write flag for vertex/geometry as compute output buffers
2023-09-05 22:59:21 +02:00
siegmund-heiss-ich
f631933e60 Add macOS Headless release workflow (#5272)
* Add macOS Headless release workflow

* Add MACH-O check before applying signature

* Rename script for consistency

* Remove redundant compiler flag

* Fix release.yml arguments + names

* Update headless.sh to include changes of pr #5398
2023-09-05 01:28:44 +02:00
gdkchan
5ff6ea6d82 Fix ShaderTools GpuAcessor default values (#5646) 2023-09-05 01:16:09 +02:00
gdkchan
c2d9c6955d Fix layer size for 3D textures with NPOT depth (#5640) 2023-09-04 20:14:08 -03:00
TSRBerry
fbe0c211c1 Use poetry run instead of spawning a shell (#5653) 2023-09-05 00:55:04 +02:00
dependabot[bot]
db0f3c0b74 ci: bump actions/checkout from 3 to 4 (#5650)
Bumps [actions/checkout](https://github.com/actions/checkout) from 3 to 4.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v3...v4)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-09-04 22:16:17 +02:00
TSRBerry
34447d7359 Fix overwriting .ryujinx-mako directory (#5651) 2023-09-04 19:14:20 +02:00
TSRBerry
5f771f5661 Update reviewers using Ryujinx-Mako command (#5635)
* Update reviewers using Ryujinx-Mako command

* Fix worklflow step 'uses' path
2023-09-04 11:39:25 +00:00
riperiperi
93cd327873 Vulkan: Device Local and higher invocation count for buffer conversions (#5623)
Just some simple changes to the buffer conversion shaders. (stride conversion, D32S8 to D24S8)

The first change is using a device local buffer for converted vertex buffers, since they're only read/written on the GPU. These paths don't trigger on NVIDIA, but if you force them to use it demonstrates the full extent writing to host owned memory from compute absolutely destroys them. AMD GPUs are less heavily affected by this issue, but since the game in question was writing 230MB from compute, I imagine it should have some effect.

The second change is allowing the buffer conversion shaders to scale their work group count. While dividing the work between 32 invocations works OK for M1 macs, it's not so great for anything with more cores like AMD GPUs, which should be able to do a lot more parallel copies. Now, it scales by roughly 100 elements per invocation.

Some stride change cases could be improved further by either limiting vertex buffer size somehow (reading the index buffer could help, but is always risky) or only updating regions that changed, rather than invalidating the whole thing.
2023-09-02 17:58:15 -03:00
Isaac Marovitz
12cbacffca Fix numeric SWKB validation (#5627)
* Fix numeric swkbd validation

* GTK
2023-09-01 20:08:42 +02:00
Ac_K
437c78e198 opus: Implement GetWorkBufferSizeExEx and GetWorkBufferSizeForMultiStreamExEx (#5624)
* opus: Implement GetWorkBufferSizeExEx and GetWorkBufferSizeForMultiStreamExEx

* Fix comments
2023-08-30 22:04:25 +02:00
52 changed files with 616 additions and 404 deletions

View File

@@ -1,87 +0,0 @@
from pathlib import Path
from typing import List, Set
from github import Auth, Github
from github.Repository import Repository
from github.GithubException import GithubException
import os
import sys
import yaml
def add_reviewers(
reviewers: Set[str], team_reviewers: Set[str], new_entries: List[str]
):
for reviewer in new_entries:
if reviewer.startswith("@"):
team_reviewers.add(reviewer[1:])
else:
reviewers.add(reviewer)
def update_reviewers(config, repo: Repository, pr_id: int) -> int:
pull_request = repo.get_pull(pr_id)
if not pull_request:
sys.stderr.writable(f"Unknown PR #{pr_id}\n")
return 1
if pull_request.draft:
print("Not assigning reviewers for draft PRs")
return 0
pull_request_author = pull_request.user.login
reviewers = set()
team_reviewers = set()
for label in pull_request.labels:
if label.name in config:
add_reviewers(reviewers, team_reviewers, config[label.name])
if "default" in config:
add_reviewers(reviewers, team_reviewers, config["default"])
if pull_request_author in reviewers:
reviewers.remove(pull_request_author)
try:
reviewers = list(reviewers)
team_reviewers = list(team_reviewers)
print(
f"Attempting to assign reviewers ({reviewers}) and team_reviewers ({team_reviewers})"
)
pull_request.create_review_request(reviewers, team_reviewers)
return 0
except GithubException as e:
sys.stderr.write(f"Cannot assign review request for PR #{pr_id}: {e}\n")
return 1
if __name__ == "__main__":
if len(sys.argv) != 7:
sys.stderr.write("usage: <app_id> <private_key_env_name> <installation_id> <repo_path> <pr_id> <config_path>\n")
sys.exit(1)
app_id = int(sys.argv[1])
private_key = os.environ[sys.argv[2]]
installation_id = int(sys.argv[3])
repo_path = sys.argv[4]
pr_id = int(sys.argv[5])
config_path = Path(sys.argv[6])
auth = Auth.AppAuth(app_id, private_key).get_installation_auth(installation_id)
g = Github(auth=auth)
repo = g.get_repo(repo_path)
if not repo:
sys.stderr.write("Repository not found!\n")
sys.exit(1)
if not config_path.exists():
sys.stderr.write(f'Config "{config_path}" not found!\n')
sys.exit(1)
with open(config_path, "r") as f:
config = yaml.safe_load(f)
sys.exit(update_reviewers(config, repo, pr_id))

View File

@@ -35,7 +35,7 @@ jobs:
fail-fast: false fail-fast: false
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
- uses: actions/setup-dotnet@v3 - uses: actions/setup-dotnet@v3
with: with:
@@ -108,7 +108,7 @@ jobs:
configuration: [ Debug, Release ] configuration: [ Debug, Release ]
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
- uses: actions/setup-dotnet@v3 - uses: actions/setup-dotnet@v3
with: with:
@@ -135,9 +135,13 @@ jobs:
id: git_short_hash id: git_short_hash
run: echo "result=$(git rev-parse --short "${{ github.sha }}")" >> $GITHUB_OUTPUT run: echo "result=$(git rev-parse --short "${{ github.sha }}")" >> $GITHUB_OUTPUT
- name: Publish macOS - name: Publish macOS Ryujinx.Ava
run: | run: |
./distribution/macos/create_macos_build.sh . publish_tmp publish_ava ./distribution/macos/entitlements.xml "${{ env.RYUJINX_BASE_VERSION }}" "${{ steps.git_short_hash.outputs.result }}" "${{ matrix.configuration }}" "-p:ExtraDefineConstants=DISABLE_UPDATER" ./distribution/macos/create_macos_build_ava.sh . publish_tmp_ava publish_ava ./distribution/macos/entitlements.xml "${{ env.RYUJINX_BASE_VERSION }}" "${{ steps.git_short_hash.outputs.result }}" "${{ matrix.configuration }}" "-p:ExtraDefineConstants=DISABLE_UPDATER"
- name: Publish macOS Ryujinx.Headless.SDL2
run: |
./distribution/macos/create_macos_build_headless.sh . publish_tmp_headless publish_headless ./distribution/macos/entitlements.xml "${{ env.RYUJINX_BASE_VERSION }}" "${{ steps.git_short_hash.outputs.result }}" "${{ matrix.configuration }}" "-p:ExtraDefineConstants=DISABLE_UPDATER"
- name: Upload Ryujinx.Ava artifact - name: Upload Ryujinx.Ava artifact
uses: actions/upload-artifact@v3 uses: actions/upload-artifact@v3
@@ -145,3 +149,10 @@ jobs:
name: ava-ryujinx-${{ matrix.configuration }}-${{ env.RYUJINX_BASE_VERSION }}+${{ steps.git_short_hash.outputs.result }}-macos_universal name: ava-ryujinx-${{ matrix.configuration }}-${{ env.RYUJINX_BASE_VERSION }}+${{ steps.git_short_hash.outputs.result }}-macos_universal
path: "publish_ava/*.tar.gz" path: "publish_ava/*.tar.gz"
if: github.event_name == 'pull_request' if: github.event_name == 'pull_request'
- name: Upload Ryujinx.Headless.SDL2 artifact
uses: actions/upload-artifact@v3
with:
name: sdl2-ryujinx-headless-${{ matrix.configuration }}-${{ env.RYUJINX_BASE_VERSION }}+${{ steps.git_short_hash.outputs.result }}-macos_universal
path: "publish_headless/*.tar.gz"
if: github.event_name == 'pull_request'

View File

@@ -23,7 +23,7 @@ jobs:
format: format:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
with: with:
fetch-depth: 0 fetch-depth: 0

View File

@@ -24,7 +24,7 @@ jobs:
RYUJINX_VERSION: "${{ inputs.ryujinx_version }}" RYUJINX_VERSION: "${{ inputs.ryujinx_version }}"
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
with: with:
path: Ryujinx path: Ryujinx
@@ -38,7 +38,7 @@ jobs:
run: | run: |
echo "git_hash=$(git rev-parse HEAD)" >> $GITHUB_OUTPUT echo "git_hash=$(git rev-parse HEAD)" >> $GITHUB_OUTPUT
- uses: actions/checkout@v3 - uses: actions/checkout@v4
with: with:
repository: flathub/org.ryujinx.Ryujinx repository: flathub/org.ryujinx.Ryujinx
token: ${{ secrets.RYUJINX_BOT_PAT }} token: ${{ secrets.RYUJINX_BOT_PAT }}

View File

@@ -12,14 +12,24 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
# Grab sources to get update_reviewers.py and reviewers.yml # Grab sources to get latest labeler.yml
- name: Fetch sources - name: Fetch sources
uses: actions/checkout@v3 uses: actions/checkout@v4
with: with:
# Ensure we pin the source origin as pull_request_target run under forks. # Ensure we pin the source origin as pull_request_target run under forks.
fetch-depth: 0 fetch-depth: 0
repository: Ryujinx/Ryujinx repository: Ryujinx/Ryujinx
ref: master ref: master
- name: Checkout Ryujinx-Mako
uses: actions/checkout@v4
with:
repository: Ryujinx/Ryujinx-Mako
ref: master
path: '.ryujinx-mako'
- name: Setup Ryujinx-Mako
uses: ./.ryujinx-mako/.github/actions/setup-mako
- name: Update labels based on changes - name: Update labels based on changes
uses: actions/labeler@v4 uses: actions/labeler@v4
@@ -27,11 +37,11 @@ jobs:
sync-labels: true sync-labels: true
dot: true dot: true
- run: pip3 install PyGithub
- name: Assign reviewers - name: Assign reviewers
run: | run: |
python3 .github/update_reviewers.py ${{ secrets.MAKO_APP_ID }} "MAKO_PRIVATE_KEY" ${{ secrets.MAKO_INSTALLATION_ID }} ${{ github.repository }} ${{ github.event.pull_request.number }} .github/reviewers.yml poetry -n -C .ryujinx-mako run ryujinx-mako update-reviewers ${{ github.repository }} ${{ github.event.pull_request.number }} .github/reviewers.yml
shell: bash shell: bash
env: env:
MAKO_APP_ID: ${{ secrets.MAKO_APP_ID }}
MAKO_PRIVATE_KEY: ${{ secrets.MAKO_PRIVATE_KEY }} MAKO_PRIVATE_KEY: ${{ secrets.MAKO_PRIVATE_KEY }}
MAKO_INSTALLATION_ID: ${{ secrets.MAKO_INSTALLATION_ID }}

View File

@@ -62,7 +62,7 @@ jobs:
DOTNET_RUNTIME_IDENTIFIER: win10-x64 DOTNET_RUNTIME_IDENTIFIER: win10-x64
RELEASE_ZIP_OS_NAME: win_x64 RELEASE_ZIP_OS_NAME: win_x64
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
- uses: actions/setup-dotnet@v3 - uses: actions/setup-dotnet@v3
with: with:
@@ -150,7 +150,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
timeout-minutes: ${{ fromJSON(vars.JOB_TIMEOUT) }} timeout-minutes: ${{ fromJSON(vars.JOB_TIMEOUT) }}
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
- uses: actions/setup-dotnet@v3 - uses: actions/setup-dotnet@v3
with: with:
@@ -188,15 +188,19 @@ jobs:
sed -r --in-place 's/\%\%RYUJINX_TARGET_RELEASE_CHANNEL_REPO\%\%/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/g;' src/Ryujinx.Common/ReleaseInformation.cs sed -r --in-place 's/\%\%RYUJINX_TARGET_RELEASE_CHANNEL_REPO\%\%/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/g;' src/Ryujinx.Common/ReleaseInformation.cs
shell: bash shell: bash
- name: Publish macOS - name: Publish macOS Ryujinx.Ava
run: | run: |
./distribution/macos/create_macos_build.sh . publish_tmp publish_ava ./distribution/macos/entitlements.xml "${{ steps.version_info.outputs.build_version }}" "${{ steps.version_info.outputs.git_short_hash }}" Release ./distribution/macos/create_macos_build_ava.sh . publish_tmp_ava publish_ava ./distribution/macos/entitlements.xml "${{ steps.version_info.outputs.build_version }}" "${{ steps.version_info.outputs.git_short_hash }}" Release
- name: Publish macOS Ryujinx.Headless.SDL2
run: |
./distribution/macos/create_macos_build_headless.sh . publish_tmp_headless publish_headless ./distribution/macos/entitlements.xml "${{ steps.version_info.outputs.build_version }}" "${{ steps.version_info.outputs.git_short_hash }}" Release
- name: Pushing new release - name: Pushing new release
uses: ncipollo/release-action@v1 uses: ncipollo/release-action@v1
with: with:
name: ${{ steps.version_info.outputs.build_version }} name: ${{ steps.version_info.outputs.build_version }}
artifacts: "publish_ava/*.tar.gz" artifacts: "publish_ava/*.tar.gz, publish_headless/*.tar.gz"
tag: ${{ steps.version_info.outputs.build_version }} tag: ${{ steps.version_info.outputs.build_version }}
body: "For more information about this release please check out the official [Changelog](https://github.com/Ryujinx/Ryujinx/wiki/Changelog)." body: "For more information about this release please check out the official [Changelog](https://github.com/Ryujinx/Ryujinx/wiki/Changelog)."
omitBodyDuringUpdate: true omitBodyDuringUpdate: true

View File

@@ -0,0 +1,111 @@
#!/bin/bash
set -e
if [ "$#" -lt 7 ]; then
echo "usage <BASE_DIR> <TEMP_DIRECTORY> <OUTPUT_DIRECTORY> <ENTITLEMENTS_FILE_PATH> <VERSION> <SOURCE_REVISION_ID> <CONFIGURATION> <EXTRA_ARGS>"
exit 1
fi
mkdir -p "$1"
mkdir -p "$2"
mkdir -p "$3"
BASE_DIR=$(readlink -f "$1")
TEMP_DIRECTORY=$(readlink -f "$2")
OUTPUT_DIRECTORY=$(readlink -f "$3")
ENTITLEMENTS_FILE_PATH=$(readlink -f "$4")
VERSION=$5
SOURCE_REVISION_ID=$6
CONFIGURATION=$7
EXTRA_ARGS=$8
if [ "$VERSION" == "1.1.0" ];
then
RELEASE_TAR_FILE_NAME=sdl2-ryujinx-headless-$CONFIGURATION-$VERSION+$SOURCE_REVISION_ID-macos_universal.tar
else
RELEASE_TAR_FILE_NAME=sdl2-ryujinx-headless-$VERSION-macos_universal.tar
fi
ARM64_OUTPUT="$TEMP_DIRECTORY/publish_arm64"
X64_OUTPUT="$TEMP_DIRECTORY/publish_x64"
UNIVERSAL_OUTPUT="$OUTPUT_DIRECTORY/publish"
EXECUTABLE_SUB_PATH=Ryujinx.Headless.SDL2
rm -rf "$TEMP_DIRECTORY"
mkdir -p "$TEMP_DIRECTORY"
DOTNET_COMMON_ARGS=(-p:DebugType=embedded -p:Version="$VERSION" -p:SourceRevisionId="$SOURCE_REVISION_ID" --self-contained true $EXTRA_ARGS)
dotnet restore
dotnet build -c "$CONFIGURATION" src/Ryujinx.Headless.SDL2
dotnet publish -c "$CONFIGURATION" -r osx-arm64 -o "$TEMP_DIRECTORY/publish_arm64" "${DOTNET_COMMON_ARGS[@]}" src/Ryujinx.Headless.SDL2
dotnet publish -c "$CONFIGURATION" -r osx-x64 -o "$TEMP_DIRECTORY/publish_x64" "${DOTNET_COMMON_ARGS[@]}" src/Ryujinx.Headless.SDL2
# Get rid of the support library for ARMeilleure for x64 (that's only for arm64)
rm -rf "$TEMP_DIRECTORY/publish_x64/libarmeilleure-jitsupport.dylib"
# Get rid of libsoundio from arm64 builds as we don't have a arm64 variant
# TODO: remove this once done
rm -rf "$TEMP_DIRECTORY/publish_arm64/libsoundio.dylib"
rm -rf "$OUTPUT_DIRECTORY"
mkdir -p "$OUTPUT_DIRECTORY"
# Let's copy one of the two different outputs and remove the executable
cp -R "$ARM64_OUTPUT/" "$UNIVERSAL_OUTPUT"
rm "$UNIVERSAL_OUTPUT/$EXECUTABLE_SUB_PATH"
# Make it libraries universal
python3 "$BASE_DIR/distribution/macos/construct_universal_dylib.py" "$ARM64_OUTPUT" "$X64_OUTPUT" "$UNIVERSAL_OUTPUT" "**/*.dylib"
if ! [ -x "$(command -v lipo)" ];
then
if ! [ -x "$(command -v llvm-lipo-14)" ];
then
LIPO=llvm-lipo
else
LIPO=llvm-lipo-14
fi
else
LIPO=lipo
fi
# Make the executable universal
$LIPO "$ARM64_OUTPUT/$EXECUTABLE_SUB_PATH" "$X64_OUTPUT/$EXECUTABLE_SUB_PATH" -output "$UNIVERSAL_OUTPUT/$EXECUTABLE_SUB_PATH" -create
# Now sign it
if ! [ -x "$(command -v codesign)" ];
then
if ! [ -x "$(command -v rcodesign)" ];
then
echo "Cannot find rcodesign on your system, please install rcodesign."
exit 1
fi
# NOTE: Currently require https://github.com/indygreg/apple-platform-rs/pull/44 to work on other OSes.
# cargo install --git "https://github.com/marysaka/apple-platform-rs" --branch "fix/adhoc-app-bundle" apple-codesign --bin "rcodesign"
echo "Using rcodesign for ad-hoc signing"
for FILE in "$UNIVERSAL_OUTPUT"/*; do
if [[ $(file "$FILE") == *"Mach-O"* ]]; then
rcodesign sign --entitlements-xml-path "$ENTITLEMENTS_FILE_PATH" "$FILE"
fi
done
else
echo "Using codesign for ad-hoc signing"
for FILE in "$UNIVERSAL_OUTPUT"/*; do
if [[ $(file "$FILE") == *"Mach-O"* ]]; then
codesign --entitlements "$ENTITLEMENTS_FILE_PATH" -f --deep -s - "$FILE"
fi
done
fi
echo "Creating archive"
pushd "$OUTPUT_DIRECTORY"
tar --exclude "publish/Ryujinx.Headless.SDL2" -cvf "$RELEASE_TAR_FILE_NAME" publish 1> /dev/null
python3 "$BASE_DIR/distribution/misc/add_tar_exec.py" "$RELEASE_TAR_FILE_NAME" "publish/Ryujinx.Headless.SDL2" "publish/Ryujinx.Headless.SDL2"
gzip -9 < "$RELEASE_TAR_FILE_NAME" > "$RELEASE_TAR_FILE_NAME.gz"
rm "$RELEASE_TAR_FILE_NAME"
popd
echo "Done"

View File

@@ -544,7 +544,7 @@
"SwkbdMinCharacters": "Must be at least {0} characters long", "SwkbdMinCharacters": "Must be at least {0} characters long",
"SwkbdMinRangeCharacters": "Must be {0}-{1} characters long", "SwkbdMinRangeCharacters": "Must be {0}-{1} characters long",
"SoftwareKeyboard": "Software Keyboard", "SoftwareKeyboard": "Software Keyboard",
"SoftwareKeyboardModeNumbersOnly": "Must be numbers only", "SoftwareKeyboardModeNumeric": "Must be 0-9 or '.' only",
"SoftwareKeyboardModeAlphabet": "Must be non CJK-characters only", "SoftwareKeyboardModeAlphabet": "Must be non CJK-characters only",
"SoftwareKeyboardModeASCII": "Must be ASCII text only", "SoftwareKeyboardModeASCII": "Must be ASCII text only",
"DialogControllerAppletMessagePlayerRange": "Application requests {0} player(s) with:\n\nTYPES: {1}\n\nPLAYERS: {2}\n\n{3}Please open Settings and reconfigure Input now or press Close.", "DialogControllerAppletMessagePlayerRange": "Application requests {0} player(s) with:\n\nTYPES: {1}\n\nPLAYERS: {2}\n\n{3}Please open Settings and reconfigure Input now or press Close.",

View File

@@ -136,10 +136,10 @@ namespace Ryujinx.Ava.UI.Controls
string localeText; string localeText;
switch (mode) switch (mode)
{ {
case KeyboardMode.NumbersOnly: case KeyboardMode.Numeric:
localeText = LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.SoftwareKeyboardModeNumbersOnly); localeText = LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.SoftwareKeyboardModeNumeric);
validationInfoText = string.IsNullOrEmpty(validationInfoText) ? localeText : string.Join("\n", validationInfoText, localeText); validationInfoText = string.IsNullOrEmpty(validationInfoText) ? localeText : string.Join("\n", validationInfoText, localeText);
_checkInput = text => text.All(char.IsDigit); _checkInput = text => text.All(NumericCharacterValidation.IsNumeric);
break; break;
case KeyboardMode.Alphabet: case KeyboardMode.Alphabet:
localeText = LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.SoftwareKeyboardModeAlphabet); localeText = LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.SoftwareKeyboardModeAlphabet);

View File

@@ -15,14 +15,6 @@ namespace Ryujinx.Graphics.GAL
BufferImage, BufferImage,
} }
public enum ResourceAccess : byte
{
None = 0,
Read = 1,
Write = 2,
ReadWrite = Read | Write,
}
[Flags] [Flags]
public enum ResourceStages : byte public enum ResourceStages : byte
{ {
@@ -81,19 +73,17 @@ namespace Ryujinx.Graphics.GAL
public int Binding { get; } public int Binding { get; }
public ResourceType Type { get; } public ResourceType Type { get; }
public ResourceStages Stages { get; } public ResourceStages Stages { get; }
public ResourceAccess Access { get; }
public ResourceUsage(int binding, ResourceType type, ResourceStages stages, ResourceAccess access) public ResourceUsage(int binding, ResourceType type, ResourceStages stages)
{ {
Binding = binding; Binding = binding;
Type = type; Type = type;
Stages = stages; Stages = stages;
Access = access;
} }
public override int GetHashCode() public override int GetHashCode()
{ {
return HashCode.Combine(Binding, Type, Stages, Access); return HashCode.Combine(Binding, Type, Stages);
} }
public override bool Equals(object obj) public override bool Equals(object obj)
@@ -103,7 +93,7 @@ namespace Ryujinx.Graphics.GAL
public bool Equals(ResourceUsage other) public bool Equals(ResourceUsage other)
{ {
return Binding == other.Binding && Type == other.Type && Stages == other.Stages && Access == other.Access; return Binding == other.Binding && Type == other.Type && Stages == other.Stages;
} }
public static bool operator ==(ResourceUsage left, ResourceUsage right) public static bool operator ==(ResourceUsage left, ResourceUsage right)

View File

@@ -490,10 +490,11 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed.ComputeDraw
/// </summary> /// </summary>
/// <param name="offset">Offset of the range</param> /// <param name="offset">Offset of the range</param>
/// <param name="size">Size of the range in bytes</param> /// <param name="size">Size of the range in bytes</param>
/// <param name="write">Indicates if the buffer contents will be modified</param>
/// <returns>Range</returns> /// <returns>Range</returns>
public BufferRange GetVertexDataBufferRange(int offset, int size) public BufferRange GetVertexDataBufferRange(int offset, int size, bool write)
{ {
return new BufferRange(_vertexDataBuffer.Handle, offset, size); return new BufferRange(_vertexDataBuffer.Handle, offset, size, write);
} }
/// <summary> /// <summary>
@@ -501,10 +502,11 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed.ComputeDraw
/// </summary> /// </summary>
/// <param name="offset">Offset of the range</param> /// <param name="offset">Offset of the range</param>
/// <param name="size">Size of the range in bytes</param> /// <param name="size">Size of the range in bytes</param>
/// <param name="write">Indicates if the buffer contents will be modified</param>
/// <returns>Range</returns> /// <returns>Range</returns>
public BufferRange GetGeometryVertexDataBufferRange(int offset, int size) public BufferRange GetGeometryVertexDataBufferRange(int offset, int size, bool write)
{ {
return new BufferRange(_geometryVertexDataBuffer.Handle, offset, size); return new BufferRange(_geometryVertexDataBuffer.Handle, offset, size, write);
} }
/// <summary> /// <summary>
@@ -512,10 +514,11 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed.ComputeDraw
/// </summary> /// </summary>
/// <param name="offset">Offset of the range</param> /// <param name="offset">Offset of the range</param>
/// <param name="size">Size of the range in bytes</param> /// <param name="size">Size of the range in bytes</param>
/// <param name="write">Indicates if the buffer contents will be modified</param>
/// <returns>Range</returns> /// <returns>Range</returns>
public BufferRange GetGeometryIndexDataBufferRange(int offset, int size) public BufferRange GetGeometryIndexDataBufferRange(int offset, int size, bool write)
{ {
return new BufferRange(_geometryIndexDataBuffer.Handle, offset, size); return new BufferRange(_geometryIndexDataBuffer.Handle, offset, size, write);
} }
/// <summary> /// <summary>

View File

@@ -202,7 +202,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed.ComputeDraw
_context.Renderer.Pipeline.SetUniformBuffers(stackalloc[] { new BufferAssignment(vertexInfoBinding, vertexInfoRange) }); _context.Renderer.Pipeline.SetUniformBuffers(stackalloc[] { new BufferAssignment(vertexInfoBinding, vertexInfoRange) });
int vertexDataBinding = _vertexAsCompute.Reservations.VertexOutputStorageBufferBinding; int vertexDataBinding = _vertexAsCompute.Reservations.VertexOutputStorageBufferBinding;
BufferRange vertexDataRange = _vacContext.GetVertexDataBufferRange(_vertexDataOffset, _vertexDataSize); BufferRange vertexDataRange = _vacContext.GetVertexDataBufferRange(_vertexDataOffset, _vertexDataSize, write: true);
_context.Renderer.Pipeline.SetStorageBuffers(stackalloc[] { new BufferAssignment(vertexDataBinding, vertexDataRange) }); _context.Renderer.Pipeline.SetStorageBuffers(stackalloc[] { new BufferAssignment(vertexDataBinding, vertexDataRange) });
_vacContext.VertexInfoBufferUpdater.Commit(); _vacContext.VertexInfoBufferUpdater.Commit();
@@ -245,9 +245,9 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed.ComputeDraw
int geometryVbBinding = _geometryAsCompute.Reservations.GeometryVertexOutputStorageBufferBinding; int geometryVbBinding = _geometryAsCompute.Reservations.GeometryVertexOutputStorageBufferBinding;
int geometryIbBinding = _geometryAsCompute.Reservations.GeometryIndexOutputStorageBufferBinding; int geometryIbBinding = _geometryAsCompute.Reservations.GeometryIndexOutputStorageBufferBinding;
BufferRange vertexDataRange = _vacContext.GetVertexDataBufferRange(_vertexDataOffset, _vertexDataSize); BufferRange vertexDataRange = _vacContext.GetVertexDataBufferRange(_vertexDataOffset, _vertexDataSize, write: false);
BufferRange vertexBuffer = _vacContext.GetGeometryVertexDataBufferRange(_geometryVertexDataOffset, _geometryVertexDataSize); BufferRange vertexBuffer = _vacContext.GetGeometryVertexDataBufferRange(_geometryVertexDataOffset, _geometryVertexDataSize, write: true);
BufferRange indexBuffer = _vacContext.GetGeometryIndexDataBufferRange(_geometryIndexDataOffset, _geometryIndexDataSize); BufferRange indexBuffer = _vacContext.GetGeometryIndexDataBufferRange(_geometryIndexDataOffset, _geometryIndexDataSize, write: true);
_context.Renderer.Pipeline.SetStorageBuffers(stackalloc[] _context.Renderer.Pipeline.SetStorageBuffers(stackalloc[]
{ {
@@ -293,8 +293,8 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed.ComputeDraw
if (_geometryAsCompute != null) if (_geometryAsCompute != null)
{ {
BufferRange vertexBuffer = _vacContext.GetGeometryVertexDataBufferRange(_geometryVertexDataOffset, _geometryVertexDataSize); BufferRange vertexBuffer = _vacContext.GetGeometryVertexDataBufferRange(_geometryVertexDataOffset, _geometryVertexDataSize, write: false);
BufferRange indexBuffer = _vacContext.GetGeometryIndexDataBufferRange(_geometryIndexDataOffset, _geometryIndexDataSize); BufferRange indexBuffer = _vacContext.GetGeometryIndexDataBufferRange(_geometryIndexDataOffset, _geometryIndexDataSize, write: false);
_context.Renderer.Pipeline.SetProgram(_vertexPassthroughProgram); _context.Renderer.Pipeline.SetProgram(_vertexPassthroughProgram);
_context.Renderer.Pipeline.SetIndexBuffer(indexBuffer, IndexType.UInt); _context.Renderer.Pipeline.SetIndexBuffer(indexBuffer, IndexType.UInt);
@@ -310,7 +310,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed.ComputeDraw
} }
else else
{ {
BufferRange vertexDataRange = _vacContext.GetVertexDataBufferRange(_vertexDataOffset, _vertexDataSize); BufferRange vertexDataRange = _vacContext.GetVertexDataBufferRange(_vertexDataOffset, _vertexDataSize, write: false);
_context.Renderer.Pipeline.SetProgram(_vertexPassthroughProgram); _context.Renderer.Pipeline.SetProgram(_vertexPassthroughProgram);
_context.Renderer.Pipeline.SetStorageBuffers(stackalloc[] { new BufferAssignment(vertexDataBinding, vertexDataRange) }); _context.Renderer.Pipeline.SetStorageBuffers(stackalloc[] { new BufferAssignment(vertexDataBinding, vertexDataRange) });

View File

@@ -22,7 +22,7 @@ namespace Ryujinx.Graphics.Gpu.Shader.DiskCache
private const ushort FileFormatVersionMajor = 1; private const ushort FileFormatVersionMajor = 1;
private const ushort FileFormatVersionMinor = 2; private const ushort FileFormatVersionMinor = 2;
private const uint FileFormatVersionPacked = ((uint)FileFormatVersionMajor << 16) | FileFormatVersionMinor; private const uint FileFormatVersionPacked = ((uint)FileFormatVersionMajor << 16) | FileFormatVersionMinor;
private const uint CodeGenVersion = 5551; private const uint CodeGenVersion = 5668;
private const string SharedTocFileName = "shared.toc"; private const string SharedTocFileName = "shared.toc";
private const string SharedDataFileName = "shared.data"; private const string SharedDataFileName = "shared.data";

View File

@@ -61,7 +61,7 @@ namespace Ryujinx.Graphics.Gpu.Shader
} }
AddDescriptor(SupportBufferStages, ResourceType.UniformBuffer, UniformSetIndex, 0, 1); AddDescriptor(SupportBufferStages, ResourceType.UniformBuffer, UniformSetIndex, 0, 1);
AddUsage(SupportBufferStages, ResourceType.UniformBuffer, ResourceAccess.Read, UniformSetIndex, 0, 1); AddUsage(SupportBufferStages, ResourceType.UniformBuffer, UniformSetIndex, 0, 1);
ResourceReservationCounts rrc = new(!context.Capabilities.SupportsTransformFeedback && tfEnabled, vertexAsCompute); ResourceReservationCounts rrc = new(!context.Capabilities.SupportsTransformFeedback && tfEnabled, vertexAsCompute);
@@ -73,16 +73,16 @@ namespace Ryujinx.Graphics.Gpu.Shader
// TODO: Handle that better? Maybe we should only set the binding that are really needed on each shader. // TODO: Handle that better? Maybe we should only set the binding that are really needed on each shader.
ResourceStages stages = vertexAsCompute ? ResourceStages.Compute | ResourceStages.Vertex : VtgStages; ResourceStages stages = vertexAsCompute ? ResourceStages.Compute | ResourceStages.Vertex : VtgStages;
PopulateDescriptorAndUsages(stages, ResourceType.UniformBuffer, ResourceAccess.Read, UniformSetIndex, 1, rrc.ReservedConstantBuffers - 1); PopulateDescriptorAndUsages(stages, ResourceType.UniformBuffer, UniformSetIndex, 1, rrc.ReservedConstantBuffers - 1);
PopulateDescriptorAndUsages(stages, ResourceType.StorageBuffer, ResourceAccess.ReadWrite, StorageSetIndex, 0, rrc.ReservedStorageBuffers); PopulateDescriptorAndUsages(stages, ResourceType.StorageBuffer, StorageSetIndex, 0, rrc.ReservedStorageBuffers);
PopulateDescriptorAndUsages(stages, ResourceType.BufferTexture, ResourceAccess.Read, TextureSetIndex, 0, rrc.ReservedTextures); PopulateDescriptorAndUsages(stages, ResourceType.BufferTexture, TextureSetIndex, 0, rrc.ReservedTextures);
PopulateDescriptorAndUsages(stages, ResourceType.BufferImage, ResourceAccess.ReadWrite, ImageSetIndex, 0, rrc.ReservedImages); PopulateDescriptorAndUsages(stages, ResourceType.BufferImage, ImageSetIndex, 0, rrc.ReservedImages);
} }
private void PopulateDescriptorAndUsages(ResourceStages stages, ResourceType type, ResourceAccess access, int setIndex, int start, int count) private void PopulateDescriptorAndUsages(ResourceStages stages, ResourceType type, int setIndex, int start, int count)
{ {
AddDescriptor(stages, type, setIndex, start, count); AddDescriptor(stages, type, setIndex, start, count);
AddUsage(stages, type, access, setIndex, start, count); AddUsage(stages, type, setIndex, start, count);
} }
/// <summary> /// <summary>
@@ -174,15 +174,14 @@ namespace Ryujinx.Graphics.Gpu.Shader
/// </summary> /// </summary>
/// <param name="stages">Shader stages where the resource is used</param> /// <param name="stages">Shader stages where the resource is used</param>
/// <param name="type">Type of the resource</param> /// <param name="type">Type of the resource</param>
/// <param name="access">How the resource is accessed by the shader stages where it is used</param>
/// <param name="setIndex">Descriptor set number where the resource will be bound</param> /// <param name="setIndex">Descriptor set number where the resource will be bound</param>
/// <param name="binding">Binding number where the resource will be bound</param> /// <param name="binding">Binding number where the resource will be bound</param>
/// <param name="count">Number of resources bound at the binding location</param> /// <param name="count">Number of resources bound at the binding location</param>
private void AddUsage(ResourceStages stages, ResourceType type, ResourceAccess access, int setIndex, int binding, int count) private void AddUsage(ResourceStages stages, ResourceType type, int setIndex, int binding, int count)
{ {
for (int index = 0; index < count; index++) for (int index = 0; index < count; index++)
{ {
_resourceUsages[setIndex].Add(new ResourceUsage(binding + index, type, stages, access)); _resourceUsages[setIndex].Add(new ResourceUsage(binding + index, type, stages));
} }
} }
@@ -200,8 +199,7 @@ namespace Ryujinx.Graphics.Gpu.Shader
_resourceUsages[setIndex].Add(new ResourceUsage( _resourceUsages[setIndex].Add(new ResourceUsage(
buffer.Binding, buffer.Binding,
isStorage ? ResourceType.StorageBuffer : ResourceType.UniformBuffer, isStorage ? ResourceType.StorageBuffer : ResourceType.UniformBuffer,
stages, stages));
buffer.Flags.HasFlag(BufferUsageFlags.Write) ? ResourceAccess.ReadWrite : ResourceAccess.Read));
} }
} }
@@ -225,8 +223,7 @@ namespace Ryujinx.Graphics.Gpu.Shader
_resourceUsages[setIndex].Add(new ResourceUsage( _resourceUsages[setIndex].Add(new ResourceUsage(
texture.Binding, texture.Binding,
type, type,
stages, stages));
texture.Flags.HasFlag(TextureUsageFlags.ImageStore) ? ResourceAccess.ReadWrite : ResourceAccess.Read));
} }
} }

View File

@@ -128,7 +128,26 @@ namespace Ryujinx.Graphics.Shader
/// <returns>GPU graphics state</returns> /// <returns>GPU graphics state</returns>
GpuGraphicsState QueryGraphicsState() GpuGraphicsState QueryGraphicsState()
{ {
return default; return new GpuGraphicsState(
false,
InputTopology.Points,
false,
TessPatchType.Triangles,
TessSpacing.EqualSpacing,
false,
false,
false,
false,
false,
1f,
AlphaTestOp.Always,
0f,
default,
true,
default,
false,
false,
false);
} }
/// <summary> /// <summary>

View File

@@ -1126,7 +1126,7 @@ namespace Ryujinx.Graphics.Shader.Translation.Optimizations
// so we want to get the byte offset back, since each one of those word // so we want to get the byte offset back, since each one of those word
// offsets are a new "local variable" which will not match. // offsets are a new "local variable" which will not match.
if (operation.GetSource(0).AsgOp is Operation shiftRightOp && if (operation.GetSource(1).AsgOp is Operation shiftRightOp &&
shiftRightOp.Inst == Instruction.ShiftRightU32 && shiftRightOp.Inst == Instruction.ShiftRightU32 &&
shiftRightOp.GetSource(1).Type == OperandType.Constant && shiftRightOp.GetSource(1).Type == OperandType.Constant &&
shiftRightOp.GetSource(1).Value == 2) shiftRightOp.GetSource(1).Value == 2)
@@ -1158,9 +1158,11 @@ namespace Ryujinx.Graphics.Shader.Translation.Optimizations
private static bool TryGetLocalMemoryOffset(Operation operation, out int constOffset) private static bool TryGetLocalMemoryOffset(Operation operation, out int constOffset)
{ {
if (operation.GetSource(0).Type == OperandType.Constant) Operand offset = operation.GetSource(1);
if (offset.Type == OperandType.Constant)
{ {
constOffset = operation.GetSource(0).Value; constOffset = offset.Value;
return true; return true;
} }

View File

@@ -38,6 +38,7 @@ namespace Ryujinx.Graphics.Texture
bool is3D = depth > 1 || gobBlocksInZ > 1; bool is3D = depth > 1 || gobBlocksInZ > 1;
int layerSize = 0; int layerSize = 0;
int layerSizeAligned = 0;
int[] allOffsets = new int[is3D ? Calculate3DOffsetCount(levels, depth) : levels * layers * depth]; int[] allOffsets = new int[is3D ? Calculate3DOffsetCount(levels, depth) : levels * layers * depth];
int[] mipOffsets = new int[levels]; int[] mipOffsets = new int[levels];
@@ -91,6 +92,8 @@ namespace Ryujinx.Graphics.Texture
sliceSizes[level] = totalBlocksOfGobsInY * robSize; sliceSizes[level] = totalBlocksOfGobsInY * robSize;
levelSizes[level] = totalBlocksOfGobsInZ * sliceSizes[level]; levelSizes[level] = totalBlocksOfGobsInZ * sliceSizes[level];
layerSizeAligned += levelSizes[level];
if (is3D) if (is3D)
{ {
int gobSize = mipGobBlocksInY * GobSize; int gobSize = mipGobBlocksInY * GobSize;
@@ -130,28 +133,32 @@ namespace Ryujinx.Graphics.Texture
depthLevelOffset += d; depthLevelOffset += d;
} }
int totalSize;
if (layers > 1) if (layers > 1)
{ {
layerSize = AlignLayerSize( layerSizeAligned = AlignLayerSize(
layerSize, layerSizeAligned,
height, height,
depth, depth,
blockHeight, blockHeight,
gobBlocksInY, gobBlocksInY,
gobBlocksInZ, gobBlocksInZ,
gobBlocksInTileX); gobBlocksInTileX);
}
int totalSize; if (layerSizeAligned < gpuLayerSize)
{
if (layerSize < gpuLayerSize) totalSize = (layers - 1) * gpuLayerSize + layerSizeAligned;
{ layerSizeAligned = gpuLayerSize;
totalSize = (layers - 1) * gpuLayerSize + layerSize; }
layerSize = gpuLayerSize; else
{
totalSize = layerSizeAligned * layers;
}
} }
else else
{ {
totalSize = layerSize * layers; totalSize = layerSize;
} }
if (!is3D) if (!is3D)
@@ -159,7 +166,7 @@ namespace Ryujinx.Graphics.Texture
for (int layer = 0; layer < layers; layer++) for (int layer = 0; layer < layers; layer++)
{ {
int baseIndex = layer * levels; int baseIndex = layer * levels;
int baseOffset = layer * layerSize; int baseOffset = layer * layerSizeAligned;
for (int level = 0; level < levels; level++) for (int level = 0; level < levels; level++)
{ {
@@ -168,7 +175,7 @@ namespace Ryujinx.Graphics.Texture
} }
} }
return new SizeInfo(mipOffsets, allOffsets, sliceSizes, levelSizes, depth, levels, layerSize, totalSize, is3D); return new SizeInfo(mipOffsets, allOffsets, sliceSizes, levelSizes, depth, levels, layerSizeAligned, totalSize, is3D);
} }
public static SizeInfo GetLinearTextureSize(int stride, int height, int blockHeight) public static SizeInfo GetLinearTextureSize(int stride, int height, int blockHeight)

View File

@@ -967,7 +967,7 @@ namespace Ryujinx.Graphics.Vulkan
if (!_cachedConvertedBuffers.TryGetValue(offset, size, key, out var holder)) if (!_cachedConvertedBuffers.TryGetValue(offset, size, key, out var holder))
{ {
holder = _gd.BufferManager.Create(_gd, (size * 2 + 3) & ~3); holder = _gd.BufferManager.Create(_gd, (size * 2 + 3) & ~3, baseType: BufferAllocationType.DeviceLocal);
_gd.PipelineInternal.EndRenderPass(); _gd.PipelineInternal.EndRenderPass();
_gd.HelperShader.ConvertI8ToI16(_gd, cbs, this, holder, offset, size); _gd.HelperShader.ConvertI8ToI16(_gd, cbs, this, holder, offset, size);
@@ -993,7 +993,7 @@ namespace Ryujinx.Graphics.Vulkan
{ {
int alignedStride = (stride + (alignment - 1)) & -alignment; int alignedStride = (stride + (alignment - 1)) & -alignment;
holder = _gd.BufferManager.Create(_gd, (size / stride) * alignedStride); holder = _gd.BufferManager.Create(_gd, (size / stride) * alignedStride, baseType: BufferAllocationType.DeviceLocal);
_gd.PipelineInternal.EndRenderPass(); _gd.PipelineInternal.EndRenderPass();
_gd.HelperShader.ChangeStride(_gd, cbs, this, holder, offset, size, stride, alignedStride); _gd.HelperShader.ChangeStride(_gd, cbs, this, holder, offset, size, stride, alignedStride);
@@ -1023,7 +1023,7 @@ namespace Ryujinx.Graphics.Vulkan
int convertedCount = pattern.GetConvertedCount(indexCount); int convertedCount = pattern.GetConvertedCount(indexCount);
holder = _gd.BufferManager.Create(_gd, convertedCount * 4); holder = _gd.BufferManager.Create(_gd, convertedCount * 4, baseType: BufferAllocationType.DeviceLocal);
_gd.PipelineInternal.EndRenderPass(); _gd.PipelineInternal.EndRenderPass();
_gd.HelperShader.ConvertIndexBuffer(_gd, cbs, this, holder, pattern, indexSize, offset, indexCount); _gd.HelperShader.ConvertIndexBuffer(_gd, cbs, this, holder, pattern, indexSize, offset, indexCount);

View File

@@ -5,7 +5,6 @@ using Ryujinx.Graphics.Shader.Translation;
using Silk.NET.Vulkan; using Silk.NET.Vulkan;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO;
using System.Numerics; using System.Numerics;
using CompareOp = Ryujinx.Graphics.GAL.CompareOp; using CompareOp = Ryujinx.Graphics.GAL.CompareOp;
using Format = Ryujinx.Graphics.GAL.Format; using Format = Ryujinx.Graphics.GAL.Format;
@@ -27,6 +26,7 @@ namespace Ryujinx.Graphics.Vulkan
class HelperShader : IDisposable class HelperShader : IDisposable
{ {
private const int UniformBufferAlignment = 256; private const int UniformBufferAlignment = 256;
private const int ConvertElementsPerWorkgroup = 32 * 100; // Work group size of 32 times 100 elements.
private const string ShaderBinariesPath = "Ryujinx.Graphics.Vulkan/Shaders/SpirvBinaries"; private const string ShaderBinariesPath = "Ryujinx.Graphics.Vulkan/Shaders/SpirvBinaries";
private readonly PipelineHelperShader _pipeline; private readonly PipelineHelperShader _pipeline;
@@ -894,7 +894,7 @@ namespace Ryujinx.Graphics.Vulkan
_pipeline.SetStorageBuffers(1, sbRanges); _pipeline.SetStorageBuffers(1, sbRanges);
_pipeline.SetProgram(_programStrideChange); _pipeline.SetProgram(_programStrideChange);
_pipeline.DispatchCompute(1, 1, 1); _pipeline.DispatchCompute(1 + elems / ConvertElementsPerWorkgroup, 1, 1);
gd.BufferManager.Delete(bufferHandle); gd.BufferManager.Delete(bufferHandle);
@@ -1742,7 +1742,7 @@ namespace Ryujinx.Graphics.Vulkan
_pipeline.SetStorageBuffers(1, sbRanges); _pipeline.SetStorageBuffers(1, sbRanges);
_pipeline.SetProgram(_programConvertD32S8ToD24S8); _pipeline.SetProgram(_programConvertD32S8ToD24S8);
_pipeline.DispatchCompute(1, 1, 1); _pipeline.DispatchCompute(1 + inSize / ConvertElementsPerWorkgroup, 1, 1);
gd.BufferManager.Delete(bufferHandle); gd.BufferManager.Delete(bufferHandle);

View File

@@ -8,15 +8,13 @@ namespace Ryujinx.Graphics.Vulkan
public readonly int Count; public readonly int Count;
public readonly ResourceType Type; public readonly ResourceType Type;
public readonly ResourceStages Stages; public readonly ResourceStages Stages;
public readonly ResourceAccess Access;
public ResourceBindingSegment(int binding, int count, ResourceType type, ResourceStages stages, ResourceAccess access) public ResourceBindingSegment(int binding, int count, ResourceType type, ResourceStages stages)
{ {
Binding = binding; Binding = binding;
Count = count; Count = count;
Type = type; Type = type;
Stages = stages; Stages = stages;
Access = access;
} }
} }
} }

View File

@@ -34,22 +34,12 @@ namespace Ryujinx.Graphics.Vulkan
_ => throw new ArgumentException($"Invalid resource type \"{type}\"."), _ => throw new ArgumentException($"Invalid resource type \"{type}\"."),
}; };
ResourceAccess access = IsReadOnlyType(type) ? ResourceAccess.Read : ResourceAccess.ReadWrite;
_resourceDescriptors[setIndex].Add(new ResourceDescriptor(binding, 1, type, stages)); _resourceDescriptors[setIndex].Add(new ResourceDescriptor(binding, 1, type, stages));
_resourceUsages[setIndex].Add(new ResourceUsage(binding, type, stages, access)); _resourceUsages[setIndex].Add(new ResourceUsage(binding, type, stages));
return this; return this;
} }
private static bool IsReadOnlyType(ResourceType type)
{
return type == ResourceType.UniformBuffer ||
type == ResourceType.Sampler ||
type == ResourceType.TextureAndSampler ||
type == ResourceType.BufferTexture;
}
public ResourceLayout Build() public ResourceLayout Build()
{ {
var descriptors = new ResourceDescriptorCollection[TotalSets]; var descriptors = new ResourceDescriptorCollection[TotalSets];

View File

@@ -162,8 +162,7 @@ namespace Ryujinx.Graphics.Vulkan
currentDescriptor.Binding, currentDescriptor.Binding,
currentCount, currentCount,
currentDescriptor.Type, currentDescriptor.Type,
currentDescriptor.Stages, currentDescriptor.Stages));
ResourceAccess.ReadWrite));
} }
currentDescriptor = descriptor; currentDescriptor = descriptor;
@@ -181,8 +180,7 @@ namespace Ryujinx.Graphics.Vulkan
currentDescriptor.Binding, currentDescriptor.Binding,
currentCount, currentCount,
currentDescriptor.Type, currentDescriptor.Type,
currentDescriptor.Stages, currentDescriptor.Stages));
ResourceAccess.ReadWrite));
} }
segments[setIndex] = currentSegments.ToArray(); segments[setIndex] = currentSegments.ToArray();
@@ -206,16 +204,9 @@ namespace Ryujinx.Graphics.Vulkan
{ {
ResourceUsage usage = setUsages[setIndex].Usages[index]; ResourceUsage usage = setUsages[setIndex].Usages[index];
// If the resource is not accessed, we don't need to update it.
if (usage.Access == ResourceAccess.None)
{
continue;
}
if (currentUsage.Binding + currentCount != usage.Binding || if (currentUsage.Binding + currentCount != usage.Binding ||
currentUsage.Type != usage.Type || currentUsage.Type != usage.Type ||
currentUsage.Stages != usage.Stages || currentUsage.Stages != usage.Stages)
currentUsage.Access != usage.Access)
{ {
if (currentCount != 0) if (currentCount != 0)
{ {
@@ -223,8 +214,7 @@ namespace Ryujinx.Graphics.Vulkan
currentUsage.Binding, currentUsage.Binding,
currentCount, currentCount,
currentUsage.Type, currentUsage.Type,
currentUsage.Stages, currentUsage.Stages));
currentUsage.Access));
} }
currentUsage = usage; currentUsage = usage;
@@ -242,8 +232,7 @@ namespace Ryujinx.Graphics.Vulkan
currentUsage.Binding, currentUsage.Binding,
currentCount, currentCount,
currentUsage.Type, currentUsage.Type,
currentUsage.Stages, currentUsage.Stages));
currentUsage.Access));
} }
segments[setIndex] = currentSegments.ToArray(); segments[setIndex] = currentSegments.ToArray();

View File

@@ -29,7 +29,7 @@ void main()
int sourceOffset = stride_arguments_data.w; int sourceOffset = stride_arguments_data.w;
int strideRemainder = targetStride - sourceStride; int strideRemainder = targetStride - sourceStride;
int invocations = int(gl_WorkGroupSize.x); int invocations = int(gl_WorkGroupSize.x * gl_NumWorkGroups.x);
int copiesRequired = bufferSize / sourceStride; int copiesRequired = bufferSize / sourceStride;
@@ -39,7 +39,7 @@ void main()
int allInvocationCopies = copiesRequired / invocations; int allInvocationCopies = copiesRequired / invocations;
// - Extra remainder copy that this invocation performs. // - Extra remainder copy that this invocation performs.
int index = int(gl_LocalInvocationID.x); int index = int(gl_GlobalInvocationID.x);
int extra = (index < (copiesRequired % invocations)) ? 1 : 0; int extra = (index < (copiesRequired % invocations)) ? 1 : 0;
int copyCount = allInvocationCopies + extra; int copyCount = allInvocationCopies + extra;

View File

@@ -23,7 +23,7 @@ layout (std430, set = 1, binding = 2) buffer out_s
void main() void main()
{ {
// Determine what slice of the stride copies this invocation will perform. // Determine what slice of the stride copies this invocation will perform.
int invocations = int(gl_WorkGroupSize.x); int invocations = int(gl_WorkGroupSize.x * gl_NumWorkGroups.x);
int copiesRequired = pixelCount; int copiesRequired = pixelCount;
@@ -33,7 +33,7 @@ void main()
int allInvocationCopies = copiesRequired / invocations; int allInvocationCopies = copiesRequired / invocations;
// - Extra remainder copy that this invocation performs. // - Extra remainder copy that this invocation performs.
int index = int(gl_LocalInvocationID.x); int index = int(gl_GlobalInvocationID.x);
int extra = (index < (copiesRequired % invocations)) ? 1 : 0; int extra = (index < (copiesRequired % invocations)) ? 1 : 0;
int copyCount = allInvocationCopies + extra; int copyCount = allInvocationCopies + extra;

View File

@@ -11,9 +11,9 @@
Default = 0, Default = 0,
/// <summary> /// <summary>
/// Only numbers allowed. /// Only 0-9 or '.' allowed.
/// </summary> /// </summary>
NumbersOnly = 1, Numeric = 1,
/// <summary> /// <summary>
/// Only ASCII characters allowed. /// Only ASCII characters allowed.

View File

@@ -0,0 +1,17 @@
using System.Text.RegularExpressions;
namespace Ryujinx.HLE.HOS.Applets.SoftwareKeyboard
{
public static partial class NumericCharacterValidation
{
public static bool IsNumeric(char value)
{
Regex regex = NumericRegex();
return regex.IsMatch(value.ToString());
}
[GeneratedRegex("[0-9]|.")]
private static partial Regex NumericRegex();
}
}

View File

@@ -68,15 +68,15 @@ namespace Ryujinx.HLE.HOS.Applets.SoftwareKeyboard
int ryujinxLogoSize = 32; int ryujinxLogoSize = 32;
string ryujinxIconPath = "Ryujinx.HLE.HOS.Applets.SoftwareKeyboard.Resources.Logo_Ryujinx.png"; string ryujinxIconPath = "Ryujinx.HLE.HOS.Applets.SoftwareKeyboard.Resources.Logo_Ryujinx.png";
_ryujinxLogo = LoadResource(Assembly.GetExecutingAssembly(), ryujinxIconPath, ryujinxLogoSize, ryujinxLogoSize); _ryujinxLogo = LoadResource(typeof(SoftwareKeyboardRendererBase).Assembly, ryujinxIconPath, ryujinxLogoSize, ryujinxLogoSize);
string padAcceptIconPath = "Ryujinx.HLE.HOS.Applets.SoftwareKeyboard.Resources.Icon_BtnA.png"; string padAcceptIconPath = "Ryujinx.HLE.HOS.Applets.SoftwareKeyboard.Resources.Icon_BtnA.png";
string padCancelIconPath = "Ryujinx.HLE.HOS.Applets.SoftwareKeyboard.Resources.Icon_BtnB.png"; string padCancelIconPath = "Ryujinx.HLE.HOS.Applets.SoftwareKeyboard.Resources.Icon_BtnB.png";
string keyModeIconPath = "Ryujinx.HLE.HOS.Applets.SoftwareKeyboard.Resources.Icon_KeyF6.png"; string keyModeIconPath = "Ryujinx.HLE.HOS.Applets.SoftwareKeyboard.Resources.Icon_KeyF6.png";
_padAcceptIcon = LoadResource(Assembly.GetExecutingAssembly(), padAcceptIconPath, 0, 0); _padAcceptIcon = LoadResource(typeof(SoftwareKeyboardRendererBase).Assembly, padAcceptIconPath, 0, 0);
_padCancelIcon = LoadResource(Assembly.GetExecutingAssembly(), padCancelIconPath, 0, 0); _padCancelIcon = LoadResource(typeof(SoftwareKeyboardRendererBase).Assembly, padCancelIconPath, 0, 0);
_keyModeIcon = LoadResource(Assembly.GetExecutingAssembly(), keyModeIconPath, 0, 0); _keyModeIcon = LoadResource(typeof(SoftwareKeyboardRendererBase).Assembly, keyModeIconPath, 0, 0);
Color panelColor = ToColor(uiTheme.DefaultBackgroundColor, 255); Color panelColor = ToColor(uiTheme.DefaultBackgroundColor, 255);
Color panelTransparentColor = ToColor(uiTheme.DefaultBackgroundColor, 150); Color panelTransparentColor = ToColor(uiTheme.DefaultBackgroundColor, 150);

View File

@@ -5,6 +5,7 @@ using Ryujinx.HLE.HOS.Services.Settings.Types;
using Ryujinx.HLE.HOS.Services.Vi.RootService.ApplicationDisplayService; using Ryujinx.HLE.HOS.Services.Vi.RootService.ApplicationDisplayService;
using Ryujinx.HLE.HOS.SystemState; using Ryujinx.HLE.HOS.SystemState;
using Ryujinx.Horizon.Common; using Ryujinx.Horizon.Common;
using Ryujinx.Horizon.Sdk.Lbl;
using System; using System;
namespace Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService.SystemAppletProxy namespace Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService.SystemAppletProxy
@@ -15,7 +16,6 @@ namespace Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService.Sys
private readonly Apm.ManagerServer _apmManagerServer; private readonly Apm.ManagerServer _apmManagerServer;
private readonly Apm.SystemManagerServer _apmSystemManagerServer; private readonly Apm.SystemManagerServer _apmSystemManagerServer;
private readonly Lbl.LblControllerServer _lblControllerServer;
private bool _vrModeEnabled; private bool _vrModeEnabled;
#pragma warning disable CS0414, IDE0052 // Remove unread private member #pragma warning disable CS0414, IDE0052 // Remove unread private member
@@ -34,7 +34,6 @@ namespace Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService.Sys
_apmManagerServer = new Apm.ManagerServer(context); _apmManagerServer = new Apm.ManagerServer(context);
_apmSystemManagerServer = new Apm.SystemManagerServer(context); _apmSystemManagerServer = new Apm.SystemManagerServer(context);
_lblControllerServer = new Lbl.LblControllerServer(context);
_acquiredSleepLockEvent = new KEvent(context.Device.System.KernelContext); _acquiredSleepLockEvent = new KEvent(context.Device.System.KernelContext);
} }
@@ -215,13 +214,15 @@ namespace Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService.Sys
_vrModeEnabled = vrModeEnabled; _vrModeEnabled = vrModeEnabled;
using var lblApi = new LblApi();
if (vrModeEnabled) if (vrModeEnabled)
{ {
_lblControllerServer.EnableVrMode(); lblApi.EnableVrMode().AbortOnFailure();
} }
else else
{ {
_lblControllerServer.DisableVrMode(); lblApi.DisableVrMode().AbortOnFailure();
} }
// TODO: It signals an internal event of ICommonStateGetter. We have to determine where this event is used. // TODO: It signals an internal event of ICommonStateGetter. We have to determine where this event is used.

View File

@@ -154,6 +154,28 @@ namespace Ryujinx.HLE.HOS.Services.Audio
return ResultCode.Success; return ResultCode.Success;
} }
[CommandCmif(8)] // 16.0.0+
// GetWorkBufferSizeExEx(OpusParametersEx) -> u32
public ResultCode GetWorkBufferSizeExEx(ServiceCtx context)
{
// NOTE: GetWorkBufferSizeEx use hardcoded values to compute the returned size.
// GetWorkBufferSizeExEx fixes that by using dynamic values.
// Since we're already doing that, it's fine to call it directly.
return GetWorkBufferSizeEx(context);
}
[CommandCmif(9)] // 16.0.0+
// GetWorkBufferSizeForMultiStreamExEx(buffer<unknown<0x118>, 0x19>) -> u32
public ResultCode GetWorkBufferSizeForMultiStreamExEx(ServiceCtx context)
{
// NOTE: GetWorkBufferSizeForMultiStreamEx use hardcoded values to compute the returned size.
// GetWorkBufferSizeForMultiStreamExEx fixes that by using dynamic values.
// Since we're already doing that, it's fine to call it directly.
return GetWorkBufferSizeForMultiStreamEx(context);
}
private static int GetOpusMultistreamDecoderSize(int streams, int coupledStreams) private static int GetOpusMultistreamDecoderSize(int streams, int coupledStreams)
{ {
if (streams < 1 || coupledStreams > streams || coupledStreams < 0) if (streams < 1 || coupledStreams > streams || coupledStreams < 0)

View File

@@ -23,14 +23,14 @@ namespace Ryujinx.HLE.HOS.Services
public IpcService(ServerBase server = null) public IpcService(ServerBase server = null)
{ {
CmifCommands = Assembly.GetExecutingAssembly().GetTypes() CmifCommands = typeof(IpcService).Assembly.GetTypes()
.Where(type => type == GetType()) .Where(type => type == GetType())
.SelectMany(type => type.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public)) .SelectMany(type => type.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public))
.SelectMany(methodInfo => methodInfo.GetCustomAttributes(typeof(CommandCmifAttribute)) .SelectMany(methodInfo => methodInfo.GetCustomAttributes(typeof(CommandCmifAttribute))
.Select(command => (((CommandCmifAttribute)command).Id, methodInfo))) .Select(command => (((CommandCmifAttribute)command).Id, methodInfo)))
.ToDictionary(command => command.Id, command => command.methodInfo); .ToDictionary(command => command.Id, command => command.methodInfo);
TipcCommands = Assembly.GetExecutingAssembly().GetTypes() TipcCommands = typeof(IpcService).Assembly.GetTypes()
.Where(type => type == GetType()) .Where(type => type == GetType())
.SelectMany(type => type.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public)) .SelectMany(type => type.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public))
.SelectMany(methodInfo => methodInfo.GetCustomAttributes(typeof(CommandTipcAttribute)) .SelectMany(methodInfo => methodInfo.GetCustomAttributes(typeof(CommandTipcAttribute))

View File

@@ -1,92 +0,0 @@
namespace Ryujinx.HLE.HOS.Services.Lbl
{
abstract class ILblController : IpcService
{
public ILblController(ServiceCtx context) { }
protected abstract void SetCurrentBrightnessSettingForVrMode(float currentBrightnessSettingForVrMode);
protected abstract float GetCurrentBrightnessSettingForVrMode();
internal abstract void EnableVrMode();
internal abstract void DisableVrMode();
protected abstract bool IsVrModeEnabled();
[CommandCmif(17)]
// SetBrightnessReflectionDelayLevel(float, float)
public ResultCode SetBrightnessReflectionDelayLevel(ServiceCtx context)
{
return ResultCode.Success;
}
[CommandCmif(18)]
// GetBrightnessReflectionDelayLevel(float) -> float
public ResultCode GetBrightnessReflectionDelayLevel(ServiceCtx context)
{
context.ResponseData.Write(0.0f);
return ResultCode.Success;
}
[CommandCmif(21)]
// SetCurrentAmbientLightSensorMapping(unknown<0xC>)
public ResultCode SetCurrentAmbientLightSensorMapping(ServiceCtx context)
{
return ResultCode.Success;
}
[CommandCmif(22)]
// GetCurrentAmbientLightSensorMapping() -> unknown<0xC>
public ResultCode GetCurrentAmbientLightSensorMapping(ServiceCtx context)
{
return ResultCode.Success;
}
[CommandCmif(24)] // 3.0.0+
// SetCurrentBrightnessSettingForVrMode(float)
public ResultCode SetCurrentBrightnessSettingForVrMode(ServiceCtx context)
{
float currentBrightnessSettingForVrMode = context.RequestData.ReadSingle();
SetCurrentBrightnessSettingForVrMode(currentBrightnessSettingForVrMode);
return ResultCode.Success;
}
[CommandCmif(25)] // 3.0.0+
// GetCurrentBrightnessSettingForVrMode() -> float
public ResultCode GetCurrentBrightnessSettingForVrMode(ServiceCtx context)
{
float currentBrightnessSettingForVrMode = GetCurrentBrightnessSettingForVrMode();
context.ResponseData.Write(currentBrightnessSettingForVrMode);
return ResultCode.Success;
}
[CommandCmif(26)] // 3.0.0+
// EnableVrMode()
public ResultCode EnableVrMode(ServiceCtx context)
{
EnableVrMode();
return ResultCode.Success;
}
[CommandCmif(27)] // 3.0.0+
// DisableVrMode()
public ResultCode DisableVrMode(ServiceCtx context)
{
DisableVrMode();
return ResultCode.Success;
}
[CommandCmif(28)] // 3.0.0+
// IsVrModeEnabled() -> bool
public ResultCode IsVrModeEnabled(ServiceCtx context)
{
context.ResponseData.Write(IsVrModeEnabled());
return ResultCode.Success;
}
}
}

View File

@@ -1,54 +0,0 @@
namespace Ryujinx.HLE.HOS.Services.Lbl
{
[Service("lbl")]
class LblControllerServer : ILblController
{
private bool _vrModeEnabled;
private float _currentBrightnessSettingForVrMode;
public LblControllerServer(ServiceCtx context) : base(context) { }
protected override void SetCurrentBrightnessSettingForVrMode(float currentBrightnessSettingForVrMode)
{
if (float.IsNaN(currentBrightnessSettingForVrMode) || float.IsInfinity(currentBrightnessSettingForVrMode))
{
_currentBrightnessSettingForVrMode = 0.0f;
return;
}
_currentBrightnessSettingForVrMode = currentBrightnessSettingForVrMode;
}
protected override float GetCurrentBrightnessSettingForVrMode()
{
if (float.IsNaN(_currentBrightnessSettingForVrMode) || float.IsInfinity(_currentBrightnessSettingForVrMode))
{
return 0.0f;
}
return _currentBrightnessSettingForVrMode;
}
internal override void EnableVrMode()
{
_vrModeEnabled = true;
// NOTE: Service check _vrModeEnabled field value in a thread and then change the screen brightness.
// Since we don't support that. It's fine to do nothing.
}
internal override void DisableVrMode()
{
_vrModeEnabled = false;
// NOTE: Service check _vrModeEnabled field value in a thread and then change the screen brightness.
// Since we don't support that. It's fine to do nothing.
}
protected override bool IsVrModeEnabled()
{
return _vrModeEnabled;
}
}
}

View File

@@ -6,6 +6,7 @@ using Ryujinx.HLE.HOS.Kernel;
using Ryujinx.HLE.HOS.Kernel.Ipc; using Ryujinx.HLE.HOS.Kernel.Ipc;
using Ryujinx.HLE.HOS.Kernel.Process; using Ryujinx.HLE.HOS.Kernel.Process;
using Ryujinx.HLE.HOS.Kernel.Threading; using Ryujinx.HLE.HOS.Kernel.Threading;
using Ryujinx.Horizon;
using Ryujinx.Horizon.Common; using Ryujinx.Horizon.Common;
using System; using System;
using System.Buffers; using System.Buffers;
@@ -172,6 +173,13 @@ namespace Ryujinx.HLE.HOS.Services
_selfProcess = KernelStatic.GetCurrentProcess(); _selfProcess = KernelStatic.GetCurrentProcess();
_selfThread = KernelStatic.GetCurrentThread(); _selfThread = KernelStatic.GetCurrentThread();
HorizonStatic.Register(
default,
_context.Syscall,
_selfProcess.CpuMemory,
_selfThread.ThreadContext,
(int)_selfThread.ThreadContext.GetX(1));
if (SmObjectFactory != null) if (SmObjectFactory != null)
{ {
_context.Syscall.ManageNamedPort(out int serverPortHandle, "sm:", 50); _context.Syscall.ManageNamedPort(out int serverPortHandle, "sm:", 50);

View File

@@ -28,7 +28,7 @@ namespace Ryujinx.HLE.HOS.Services.Sm
static IUserInterface() static IUserInterface()
{ {
_services = Assembly.GetExecutingAssembly().GetTypes() _services = typeof(IUserInterface).Assembly.GetTypes()
.SelectMany(type => type.GetCustomAttributes(typeof(ServiceAttribute), true) .SelectMany(type => type.GetCustomAttributes(typeof(ServiceAttribute), true)
.Select(service => (((ServiceAttribute)service).Name, type))) .Select(service => (((ServiceAttribute)service).Name, type)))
.ToDictionary(service => service.Name, service => service.type); .ToDictionary(service => service.Name, service => service.type);

View File

@@ -17,7 +17,6 @@ using System.Collections.Concurrent;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.IO; using System.IO;
using System.Reflection;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Threading; using System.Threading;
using static SDL2.SDL; using static SDL2.SDL;
@@ -122,7 +121,7 @@ namespace Ryujinx.Headless.SDL2
private void SetWindowIcon() private void SetWindowIcon()
{ {
Stream iconStream = Assembly.GetExecutingAssembly().GetManifestResourceStream("Ryujinx.Headless.SDL2.Ryujinx.bmp"); Stream iconStream = typeof(WindowBase).Assembly.GetManifestResourceStream("Ryujinx.Headless.SDL2.Ryujinx.bmp");
byte[] iconBytes = new byte[iconStream!.Length]; byte[] iconBytes = new byte[iconStream!.Length];
if (iconStream.Read(iconBytes, 0, iconBytes.Length) != iconBytes.Length) if (iconStream.Read(iconBytes, 0, iconBytes.Length) != iconBytes.Length)

View File

@@ -6,8 +6,8 @@ namespace Ryujinx.Horizon.Bcat
{ {
internal class BcatIpcServer internal class BcatIpcServer
{ {
private const int BcatMaxSessionsCount = 8; private const int MaxSessionsCount = 8;
private const int BcatTotalMaxSessionsCount = BcatMaxSessionsCount * 4; private const int TotalMaxSessionsCount = MaxSessionsCount * 4;
private const int PointerBufferSize = 0x400; private const int PointerBufferSize = 0x400;
private const int MaxDomains = 64; private const int MaxDomains = 64;
@@ -17,7 +17,7 @@ namespace Ryujinx.Horizon.Bcat
private SmApi _sm; private SmApi _sm;
private BcatServerManager _serverManager; private BcatServerManager _serverManager;
private static readonly ManagerOptions _bcatManagerOptions = new(PointerBufferSize, MaxDomains, MaxDomainObjects, false); private static readonly ManagerOptions _managerOptions = new(PointerBufferSize, MaxDomains, MaxDomainObjects, false);
internal void Initialize() internal void Initialize()
{ {
@@ -26,13 +26,13 @@ namespace Ryujinx.Horizon.Bcat
_sm = new SmApi(); _sm = new SmApi();
_sm.Initialize().AbortOnFailure(); _sm.Initialize().AbortOnFailure();
_serverManager = new BcatServerManager(allocator, _sm, MaxPortsCount, _bcatManagerOptions, BcatTotalMaxSessionsCount); _serverManager = new BcatServerManager(allocator, _sm, MaxPortsCount, _managerOptions, TotalMaxSessionsCount);
#pragma warning disable IDE0055 // Disable formatting #pragma warning disable IDE0055 // Disable formatting
_serverManager.RegisterServer((int)BcatPortIndex.Admin, ServiceName.Encode("bcat:a"), BcatMaxSessionsCount); _serverManager.RegisterServer((int)BcatPortIndex.Admin, ServiceName.Encode("bcat:a"), MaxSessionsCount);
_serverManager.RegisterServer((int)BcatPortIndex.Manager, ServiceName.Encode("bcat:m"), BcatMaxSessionsCount); _serverManager.RegisterServer((int)BcatPortIndex.Manager, ServiceName.Encode("bcat:m"), MaxSessionsCount);
_serverManager.RegisterServer((int)BcatPortIndex.User, ServiceName.Encode("bcat:u"), BcatMaxSessionsCount); _serverManager.RegisterServer((int)BcatPortIndex.User, ServiceName.Encode("bcat:u"), MaxSessionsCount);
_serverManager.RegisterServer((int)BcatPortIndex.System, ServiceName.Encode("bcat:s"), BcatMaxSessionsCount); _serverManager.RegisterServer((int)BcatPortIndex.System, ServiceName.Encode("bcat:s"), MaxSessionsCount);
#pragma warning restore IDE0055 #pragma warning restore IDE0055
} }

View File

@@ -4,7 +4,7 @@ using System;
namespace Ryujinx.Horizon namespace Ryujinx.Horizon
{ {
static class HorizonStatic public static class HorizonStatic
{ {
[ThreadStatic] [ThreadStatic]
private static HorizonOptions _options; private static HorizonOptions _options;

View File

@@ -0,0 +1,130 @@
using Ryujinx.Horizon.Common;
using Ryujinx.Horizon.Sdk.Lbl;
using Ryujinx.Horizon.Sdk.Sf;
namespace Ryujinx.Horizon.Lbl.Ipc
{
partial class LblController : ILblController
{
private bool _vrModeEnabled;
private float _currentBrightnessSettingForVrMode;
[CmifCommand(17)]
public Result SetBrightnessReflectionDelayLevel(float unknown0, float unknown1)
{
// NOTE: Stubbed in system module.
return Result.Success;
}
[CmifCommand(18)]
public Result GetBrightnessReflectionDelayLevel(out float unknown1, float unknown0)
{
// NOTE: Stubbed in system module.
unknown1 = 0.0f;
return Result.Success;
}
[CmifCommand(19)]
public Result SetCurrentBrightnessMapping(float unknown0, float unknown1, float unknown2)
{
// NOTE: Stubbed in system module.
return Result.Success;
}
[CmifCommand(20)]
public Result GetCurrentBrightnessMapping(out float unknown0, out float unknown1, out float unknown2)
{
// NOTE: Stubbed in system module.
unknown0 = 0.0f;
unknown1 = 0.0f;
unknown2 = 0.0f;
return Result.Success;
}
[CmifCommand(21)]
public Result SetCurrentAmbientLightSensorMapping(float unknown0, float unknown1, float unknown2)
{
// NOTE: Stubbed in system module.
return Result.Success;
}
[CmifCommand(22)]
public Result GetCurrentAmbientLightSensorMapping(out float unknown0, out float unknown1, out float unknown2)
{
// NOTE: Stubbed in system module.
unknown0 = 0.0f;
unknown1 = 0.0f;
unknown2 = 0.0f;
return Result.Success;
}
[CmifCommand(24)]
public Result SetCurrentBrightnessSettingForVrMode(float currentBrightnessSettingForVrMode)
{
if (float.IsNaN(currentBrightnessSettingForVrMode) || float.IsInfinity(currentBrightnessSettingForVrMode))
{
_currentBrightnessSettingForVrMode = 0.0f;
}
else
{
_currentBrightnessSettingForVrMode = currentBrightnessSettingForVrMode;
}
return Result.Success;
}
[CmifCommand(25)]
public Result GetCurrentBrightnessSettingForVrMode(out float currentBrightnessSettingForVrMode)
{
if (float.IsNaN(_currentBrightnessSettingForVrMode) || float.IsInfinity(_currentBrightnessSettingForVrMode))
{
currentBrightnessSettingForVrMode = 0.0f;
}
else
{
currentBrightnessSettingForVrMode = _currentBrightnessSettingForVrMode;
}
return Result.Success;
}
[CmifCommand(26)]
public Result EnableVrMode()
{
_vrModeEnabled = true;
// NOTE: The service checks _vrModeEnabled field value in a thread and then changes the screen brightness.
// Since we don't support that, it's fine to do nothing.
return Result.Success;
}
[CmifCommand(27)]
public Result DisableVrMode()
{
_vrModeEnabled = false;
// NOTE: The service checks _vrModeEnabled field value in a thread and then changes the screen brightness.
// Since we don't support that, it's fine to do nothing.
return Result.Success;
}
[CmifCommand(28)]
public Result IsVrModeEnabled(out bool vrModeEnabled)
{
vrModeEnabled = _vrModeEnabled;
return Result.Success;
}
}
}

View File

@@ -0,0 +1,43 @@
using Ryujinx.Horizon.Lbl.Ipc;
using Ryujinx.Horizon.Sdk.Sf.Hipc;
using Ryujinx.Horizon.Sdk.Sm;
namespace Ryujinx.Horizon.Lbl
{
class LblIpcServer
{
private const int MaxSessionsCount = 5;
private const int PointerBufferSize = 0;
private const int MaxDomains = 0;
private const int MaxDomainObjects = 0;
private const int MaxPortsCount = 1;
private static readonly ManagerOptions _managerOptions = new(PointerBufferSize, MaxDomains, MaxDomainObjects, false);
private SmApi _sm;
private ServerManager _serverManager;
public void Initialize()
{
HeapAllocator allocator = new();
_sm = new SmApi();
_sm.Initialize().AbortOnFailure();
_serverManager = new ServerManager(allocator, _sm, MaxPortsCount, _managerOptions, MaxSessionsCount);
_serverManager.RegisterObjectForServer(new LblController(), ServiceName.Encode("lbl"), MaxSessionsCount);
}
public void ServiceRequests()
{
_serverManager.ServiceRequests();
}
public void Shutdown()
{
_serverManager.Dispose();
}
}
}

View File

@@ -0,0 +1,17 @@
namespace Ryujinx.Horizon.Lbl
{
class LblMain : IService
{
public static void Main(ServiceTable serviceTable)
{
LblIpcServer ipcServer = new();
ipcServer.Initialize();
serviceTable.SignalServiceReady();
ipcServer.ServiceRequests();
ipcServer.Shutdown();
}
}
}

View File

@@ -6,14 +6,14 @@ namespace Ryujinx.Horizon.LogManager
{ {
class LmIpcServer class LmIpcServer
{ {
private const int LogMaxSessionsCount = 42; private const int MaxSessionsCount = 42;
private const int PointerBufferSize = 0x400; private const int PointerBufferSize = 0x400;
private const int MaxDomains = 31; private const int MaxDomains = 31;
private const int MaxDomainObjects = 61; private const int MaxDomainObjects = 61;
private const int MaxPortsCount = 1; private const int MaxPortsCount = 1;
private static readonly ManagerOptions _logManagerOptions = new(PointerBufferSize, MaxDomains, MaxDomainObjects, false); private static readonly ManagerOptions _managerOptions = new(PointerBufferSize, MaxDomains, MaxDomainObjects, false);
private SmApi _sm; private SmApi _sm;
private ServerManager _serverManager; private ServerManager _serverManager;
@@ -25,9 +25,9 @@ namespace Ryujinx.Horizon.LogManager
_sm = new SmApi(); _sm = new SmApi();
_sm.Initialize().AbortOnFailure(); _sm.Initialize().AbortOnFailure();
_serverManager = new ServerManager(allocator, _sm, MaxPortsCount, _logManagerOptions, LogMaxSessionsCount); _serverManager = new ServerManager(allocator, _sm, MaxPortsCount, _managerOptions, MaxSessionsCount);
_serverManager.RegisterObjectForServer(new LogService(), ServiceName.Encode("lm"), LogMaxSessionsCount); _serverManager.RegisterObjectForServer(new LogService(), ServiceName.Encode("lm"), MaxSessionsCount);
} }
public void ServiceRequests() public void ServiceRequests()

View File

@@ -6,14 +6,14 @@ namespace Ryujinx.Horizon.MmNv
{ {
class MmNvIpcServer class MmNvIpcServer
{ {
private const int MmNvMaxSessionsCount = 9; private const int MaxSessionsCount = 40;
private const int PointerBufferSize = 0; private const int PointerBufferSize = 0;
private const int MaxDomains = 0; private const int MaxDomains = 0;
private const int MaxDomainObjects = 0; private const int MaxDomainObjects = 0;
private const int MaxPortsCount = 1; private const int MaxPortsCount = 1;
private static readonly ManagerOptions _mmNvOptions = new(PointerBufferSize, MaxDomains, MaxDomainObjects, false); private static readonly ManagerOptions _managerOptions = new(PointerBufferSize, MaxDomains, MaxDomainObjects, false);
private SmApi _sm; private SmApi _sm;
private ServerManager _serverManager; private ServerManager _serverManager;
@@ -25,9 +25,9 @@ namespace Ryujinx.Horizon.MmNv
_sm = new SmApi(); _sm = new SmApi();
_sm.Initialize().AbortOnFailure(); _sm.Initialize().AbortOnFailure();
_serverManager = new ServerManager(allocator, _sm, MaxPortsCount, _mmNvOptions, MmNvMaxSessionsCount); _serverManager = new ServerManager(allocator, _sm, MaxPortsCount, _managerOptions, MaxSessionsCount);
_serverManager.RegisterObjectForServer(new Request(), ServiceName.Encode("mm:u"), MmNvMaxSessionsCount); _serverManager.RegisterObjectForServer(new Request(), ServiceName.Encode("mm:u"), MaxSessionsCount);
} }
public void ServiceRequests() public void ServiceRequests()

View File

@@ -6,15 +6,15 @@ namespace Ryujinx.Horizon.Prepo
{ {
class PrepoIpcServer class PrepoIpcServer
{ {
private const int PrepoMaxSessionsCount = 12; private const int MaxSessionsCount = 12;
private const int PrepoTotalMaxSessionsCount = PrepoMaxSessionsCount * 6; private const int TotalMaxSessionsCount = MaxSessionsCount * 6;
private const int PointerBufferSize = 0x80; private const int PointerBufferSize = 0x80;
private const int MaxDomains = 64; private const int MaxDomains = 64;
private const int MaxDomainObjects = 16; private const int MaxDomainObjects = 16;
private const int MaxPortsCount = 6; private const int MaxPortsCount = 6;
private static readonly ManagerOptions _prepoManagerOptions = new(PointerBufferSize, MaxDomains, MaxDomainObjects, false); private static readonly ManagerOptions _managerOptions = new(PointerBufferSize, MaxDomains, MaxDomainObjects, false);
private SmApi _sm; private SmApi _sm;
private PrepoServerManager _serverManager; private PrepoServerManager _serverManager;
@@ -26,15 +26,15 @@ namespace Ryujinx.Horizon.Prepo
_sm = new SmApi(); _sm = new SmApi();
_sm.Initialize().AbortOnFailure(); _sm.Initialize().AbortOnFailure();
_serverManager = new PrepoServerManager(allocator, _sm, MaxPortsCount, _prepoManagerOptions, PrepoTotalMaxSessionsCount); _serverManager = new PrepoServerManager(allocator, _sm, MaxPortsCount, _managerOptions, TotalMaxSessionsCount);
#pragma warning disable IDE0055 // Disable formatting #pragma warning disable IDE0055 // Disable formatting
_serverManager.RegisterServer((int)PrepoPortIndex.Admin, ServiceName.Encode("prepo:a"), PrepoMaxSessionsCount); // 1.0.0-5.1.0 _serverManager.RegisterServer((int)PrepoPortIndex.Admin, ServiceName.Encode("prepo:a"), MaxSessionsCount); // 1.0.0-5.1.0
_serverManager.RegisterServer((int)PrepoPortIndex.Admin2, ServiceName.Encode("prepo:a2"), PrepoMaxSessionsCount); // 6.0.0+ _serverManager.RegisterServer((int)PrepoPortIndex.Admin2, ServiceName.Encode("prepo:a2"), MaxSessionsCount); // 6.0.0+
_serverManager.RegisterServer((int)PrepoPortIndex.Manager, ServiceName.Encode("prepo:m"), PrepoMaxSessionsCount); _serverManager.RegisterServer((int)PrepoPortIndex.Manager, ServiceName.Encode("prepo:m"), MaxSessionsCount);
_serverManager.RegisterServer((int)PrepoPortIndex.User, ServiceName.Encode("prepo:u"), PrepoMaxSessionsCount); _serverManager.RegisterServer((int)PrepoPortIndex.User, ServiceName.Encode("prepo:u"), MaxSessionsCount);
_serverManager.RegisterServer((int)PrepoPortIndex.System, ServiceName.Encode("prepo:s"), PrepoMaxSessionsCount); _serverManager.RegisterServer((int)PrepoPortIndex.System, ServiceName.Encode("prepo:s"), MaxSessionsCount);
_serverManager.RegisterServer((int)PrepoPortIndex.Debug, ServiceName.Encode("prepo:d"), PrepoMaxSessionsCount); // 1.0.0 _serverManager.RegisterServer((int)PrepoPortIndex.Debug, ServiceName.Encode("prepo:d"), MaxSessionsCount); // 1.0.0
#pragma warning restore IDE0055 #pragma warning restore IDE0055
} }

View File

@@ -0,0 +1,20 @@
using Ryujinx.Horizon.Common;
using Ryujinx.Horizon.Sdk.Sf;
namespace Ryujinx.Horizon.Sdk.Lbl
{
interface ILblController : IServiceObject
{
Result SetBrightnessReflectionDelayLevel(float unknown0, float unknown1);
Result GetBrightnessReflectionDelayLevel(out float unknown1, float unknown0);
Result SetCurrentBrightnessMapping(float unknown0, float unknown1, float unknown2);
Result GetCurrentBrightnessMapping(out float unknown0, out float unknown1, out float unknown2);
Result SetCurrentAmbientLightSensorMapping(float unknown0, float unknown1, float unknown2);
Result GetCurrentAmbientLightSensorMapping(out float unknown0, out float unknown1, out float unknown2);
Result SetCurrentBrightnessSettingForVrMode(float currentBrightnessSettingForVrMode);
Result GetCurrentBrightnessSettingForVrMode(out float currentBrightnessSettingForVrMode);
Result EnableVrMode();
Result DisableVrMode();
Result IsVrModeEnabled(out bool vrModeEnabled);
}
}

View File

@@ -0,0 +1,43 @@
using Ryujinx.Horizon.Common;
using Ryujinx.Horizon.Sdk.Sm;
using System;
namespace Ryujinx.Horizon.Sdk.Lbl
{
public class LblApi : IDisposable
{
private const string LblName = "lbl";
private int _sessionHandle;
public LblApi()
{
using var smApi = new SmApi();
smApi.Initialize();
smApi.GetServiceHandle(out _sessionHandle, ServiceName.Encode(LblName)).AbortOnFailure();
}
public Result EnableVrMode()
{
return ServiceUtil.SendRequest(out _, _sessionHandle, 26, sendPid: false, ReadOnlySpan<byte>.Empty);
}
public Result DisableVrMode()
{
return ServiceUtil.SendRequest(out _, _sessionHandle, 27, sendPid: false, ReadOnlySpan<byte>.Empty);
}
public void Dispose()
{
if (_sessionHandle != 0)
{
HorizonStatic.Syscall.CloseHandle(_sessionHandle);
_sessionHandle = 0;
}
GC.SuppressFinalize(this);
}
}
}

View File

@@ -4,7 +4,7 @@ using System.Runtime.InteropServices;
namespace Ryujinx.Horizon.Sdk.Sm namespace Ryujinx.Horizon.Sdk.Sm
{ {
[StructLayout(LayoutKind.Sequential, Pack = 1)] [StructLayout(LayoutKind.Sequential, Pack = 1)]
readonly struct ServiceName public readonly struct ServiceName
{ {
public static ServiceName Invalid { get; } = new(0); public static ServiceName Invalid { get; } = new(0);

View File

@@ -5,7 +5,7 @@ using System;
namespace Ryujinx.Horizon.Sdk.Sm namespace Ryujinx.Horizon.Sdk.Sm
{ {
class SmApi public class SmApi : IDisposable
{ {
private const string SmName = "sm:"; private const string SmName = "sm:";
@@ -109,5 +109,17 @@ namespace Ryujinx.Horizon.Sdk.Sm
return ServiceUtil.SendRequest(out _, _portHandle, 4, sendPid: true, data); return ServiceUtil.SendRequest(out _, _portHandle, 4, sendPid: true, data);
} }
public void Dispose()
{
if (_portHandle != 0)
{
HorizonStatic.Syscall.CloseHandle(_portHandle);
_portHandle = 0;
}
GC.SuppressFinalize(this);
}
} }
} }

View File

@@ -1,4 +1,5 @@
using Ryujinx.Horizon.Bcat; using Ryujinx.Horizon.Bcat;
using Ryujinx.Horizon.Lbl;
using Ryujinx.Horizon.LogManager; using Ryujinx.Horizon.LogManager;
using Ryujinx.Horizon.MmNv; using Ryujinx.Horizon.MmNv;
using Ryujinx.Horizon.Prepo; using Ryujinx.Horizon.Prepo;
@@ -23,10 +24,11 @@ namespace Ryujinx.Horizon
entries.Add(new ServiceEntry(T.Main, this, options)); entries.Add(new ServiceEntry(T.Main, this, options));
} }
RegisterService<LmMain>();
RegisterService<PrepoMain>();
RegisterService<BcatMain>(); RegisterService<BcatMain>();
RegisterService<LblMain>();
RegisterService<LmMain>();
RegisterService<MmNvMain>(); RegisterService<MmNvMain>();
RegisterService<PrepoMain>();
_totalServices = entries.Count; _totalServices = entries.Count;

View File

@@ -90,9 +90,9 @@ namespace Ryujinx.Ui.Applet
switch (mode) switch (mode)
{ {
case KeyboardMode.NumbersOnly: case KeyboardMode.Numeric:
_validationInfoText += "<i>Must be numbers only.</i>"; _validationInfoText += "<i>Must be 0-9 or '.' only.</i>";
_checkInput = text => text.All(char.IsDigit); _checkInput = text => text.All(NumericCharacterValidation.IsNumeric);
break; break;
case KeyboardMode.Alphabet: case KeyboardMode.Alphabet:
_validationInfoText += "<i>Must be non CJK-characters only.</i>"; _validationInfoText += "<i>Must be non CJK-characters only.</i>";