Compare commits
6 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
21ce8a9b80 | ||
![]() |
9ecbee8032 | ||
![]() |
80519af67d | ||
![]() |
26e30faff3 | ||
![]() |
0992310b76 | ||
![]() |
009c1101d2 |
11
.github/workflows/release.yml
vendored
11
.github/workflows/release.yml
vendored
@@ -112,6 +112,17 @@ jobs:
|
|||||||
repo: ${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}
|
repo: ${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}
|
||||||
token: ${{ secrets.RELEASE_TOKEN }}
|
token: ${{ secrets.RELEASE_TOKEN }}
|
||||||
|
|
||||||
|
- name: Create tag
|
||||||
|
uses: actions/github-script@v5
|
||||||
|
with:
|
||||||
|
script: |
|
||||||
|
github.rest.git.createRef({
|
||||||
|
owner: context.repo.owner,
|
||||||
|
repo: context.repo.repo,
|
||||||
|
ref: 'refs/tags/${{ steps.version_info.outputs.build_version }}',
|
||||||
|
sha: context.sha
|
||||||
|
})
|
||||||
|
|
||||||
flatpak_release:
|
flatpak_release:
|
||||||
uses: ./.github/workflows/flatpak.yml
|
uses: ./.github/workflows/flatpak.yml
|
||||||
needs: release
|
needs: release
|
||||||
|
@@ -34,6 +34,12 @@ namespace ARMeilleure.CodeGen.X86
|
|||||||
|
|
||||||
private static uint GetXcr0Eax()
|
private static uint GetXcr0Eax()
|
||||||
{
|
{
|
||||||
|
if (!FeatureInfo1Ecx.HasFlag(FeatureFlags1Ecx.Xsave))
|
||||||
|
{
|
||||||
|
// XSAVE feature required for xgetbv
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
ReadOnlySpan<byte> asmGetXcr0 = new byte[]
|
ReadOnlySpan<byte> asmGetXcr0 = new byte[]
|
||||||
{
|
{
|
||||||
0x31, 0xc9, // xor ecx, ecx
|
0x31, 0xc9, // xor ecx, ecx
|
||||||
@@ -70,6 +76,7 @@ namespace ARMeilleure.CodeGen.X86
|
|||||||
Sse42 = 1 << 20,
|
Sse42 = 1 << 20,
|
||||||
Popcnt = 1 << 23,
|
Popcnt = 1 << 23,
|
||||||
Aes = 1 << 25,
|
Aes = 1 << 25,
|
||||||
|
Xsave = 1 << 26,
|
||||||
Osxsave = 1 << 27,
|
Osxsave = 1 << 27,
|
||||||
Avx = 1 << 28,
|
Avx = 1 << 28,
|
||||||
F16c = 1 << 29
|
F16c = 1 << 29
|
||||||
@@ -118,9 +125,9 @@ namespace ARMeilleure.CodeGen.X86
|
|||||||
public static bool SupportsSse42 => FeatureInfo1Ecx.HasFlag(FeatureFlags1Ecx.Sse42);
|
public static bool SupportsSse42 => FeatureInfo1Ecx.HasFlag(FeatureFlags1Ecx.Sse42);
|
||||||
public static bool SupportsPopcnt => FeatureInfo1Ecx.HasFlag(FeatureFlags1Ecx.Popcnt);
|
public static bool SupportsPopcnt => FeatureInfo1Ecx.HasFlag(FeatureFlags1Ecx.Popcnt);
|
||||||
public static bool SupportsAesni => FeatureInfo1Ecx.HasFlag(FeatureFlags1Ecx.Aes);
|
public static bool SupportsAesni => FeatureInfo1Ecx.HasFlag(FeatureFlags1Ecx.Aes);
|
||||||
public static bool SupportsAvx => FeatureInfo1Ecx.HasFlag(FeatureFlags1Ecx.Avx | FeatureFlags1Ecx.Osxsave) && Xcr0InfoEax.HasFlag(Xcr0FlagsEax.Sse | Xcr0FlagsEax.YmmHi128);
|
public static bool SupportsAvx => FeatureInfo1Ecx.HasFlag(FeatureFlags1Ecx.Avx | FeatureFlags1Ecx.Xsave | FeatureFlags1Ecx.Osxsave) && Xcr0InfoEax.HasFlag(Xcr0FlagsEax.Sse | Xcr0FlagsEax.YmmHi128);
|
||||||
public static bool SupportsAvx2 => FeatureInfo7Ebx.HasFlag(FeatureFlags7Ebx.Avx2) && SupportsAvx;
|
public static bool SupportsAvx2 => FeatureInfo7Ebx.HasFlag(FeatureFlags7Ebx.Avx2) && SupportsAvx;
|
||||||
public static bool SupportsAvx512F => FeatureInfo7Ebx.HasFlag(FeatureFlags7Ebx.Avx512f) && FeatureInfo1Ecx.HasFlag(FeatureFlags1Ecx.Osxsave)
|
public static bool SupportsAvx512F => FeatureInfo7Ebx.HasFlag(FeatureFlags7Ebx.Avx512f) && FeatureInfo1Ecx.HasFlag(FeatureFlags1Ecx.Xsave | FeatureFlags1Ecx.Osxsave)
|
||||||
&& Xcr0InfoEax.HasFlag(Xcr0FlagsEax.Sse | Xcr0FlagsEax.YmmHi128 | Xcr0FlagsEax.Opmask | Xcr0FlagsEax.ZmmHi256 | Xcr0FlagsEax.Hi16Zmm);
|
&& Xcr0InfoEax.HasFlag(Xcr0FlagsEax.Sse | Xcr0FlagsEax.YmmHi128 | Xcr0FlagsEax.Opmask | Xcr0FlagsEax.ZmmHi256 | Xcr0FlagsEax.Hi16Zmm);
|
||||||
public static bool SupportsAvx512Vl => FeatureInfo7Ebx.HasFlag(FeatureFlags7Ebx.Avx512vl) && SupportsAvx512F;
|
public static bool SupportsAvx512Vl => FeatureInfo7Ebx.HasFlag(FeatureFlags7Ebx.Avx512vl) && SupportsAvx512F;
|
||||||
public static bool SupportsAvx512Bw => FeatureInfo7Ebx.HasFlag(FeatureFlags7Ebx.Avx512bw) && SupportsAvx512F;
|
public static bool SupportsAvx512Bw => FeatureInfo7Ebx.HasFlag(FeatureFlags7Ebx.Avx512bw) && SupportsAvx512F;
|
||||||
|
@@ -34,7 +34,7 @@
|
|||||||
<PackageVersion Include="Ryujinx.Graphics.Nvdec.Dependencies" Version="5.0.1-build13" />
|
<PackageVersion Include="Ryujinx.Graphics.Nvdec.Dependencies" Version="5.0.1-build13" />
|
||||||
<PackageVersion Include="Ryujinx.Graphics.Vulkan.Dependencies.MoltenVK" Version="1.2.0" />
|
<PackageVersion Include="Ryujinx.Graphics.Vulkan.Dependencies.MoltenVK" Version="1.2.0" />
|
||||||
<PackageVersion Include="Ryujinx.GtkSharp" Version="3.24.24.59-ryujinx" />
|
<PackageVersion Include="Ryujinx.GtkSharp" Version="3.24.24.59-ryujinx" />
|
||||||
<PackageVersion Include="Ryujinx.SDL2-CS" Version="2.26.1-build23" />
|
<PackageVersion Include="Ryujinx.SDL2-CS" Version="2.26.3-build25" />
|
||||||
<PackageVersion Include="shaderc.net" Version="0.1.0" />
|
<PackageVersion Include="shaderc.net" Version="0.1.0" />
|
||||||
<PackageVersion Include="SharpZipLib" Version="1.4.2" />
|
<PackageVersion Include="SharpZipLib" Version="1.4.2" />
|
||||||
<PackageVersion Include="Silk.NET.Vulkan" Version="2.16.0" />
|
<PackageVersion Include="Silk.NET.Vulkan" Version="2.16.0" />
|
||||||
|
@@ -180,7 +180,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
|||||||
|
|
||||||
int firstInstance = (int)_state.State.FirstInstance;
|
int firstInstance = (int)_state.State.FirstInstance;
|
||||||
|
|
||||||
int inlineIndexCount = _drawState.IbStreamer.GetAndResetInlineIndexCount();
|
int inlineIndexCount = _drawState.IbStreamer.GetAndResetInlineIndexCount(_context.Renderer);
|
||||||
|
|
||||||
if (inlineIndexCount != 0)
|
if (inlineIndexCount != 0)
|
||||||
{
|
{
|
||||||
@@ -670,7 +670,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
|||||||
{
|
{
|
||||||
if (indexedInline)
|
if (indexedInline)
|
||||||
{
|
{
|
||||||
int inlineIndexCount = _drawState.IbStreamer.GetAndResetInlineIndexCount();
|
int inlineIndexCount = _drawState.IbStreamer.GetAndResetInlineIndexCount(_context.Renderer);
|
||||||
BufferRange br = new BufferRange(_drawState.IbStreamer.GetInlineIndexBuffer(), 0, inlineIndexCount * 4);
|
BufferRange br = new BufferRange(_drawState.IbStreamer.GetInlineIndexBuffer(), 0, inlineIndexCount * 4);
|
||||||
|
|
||||||
_channel.BufferManager.SetIndexBuffer(br, IndexType.UInt);
|
_channel.BufferManager.SetIndexBuffer(br, IndexType.UInt);
|
||||||
|
@@ -11,9 +11,13 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
struct IbStreamer
|
struct IbStreamer
|
||||||
{
|
{
|
||||||
|
private const int BufferCapacity = 256; // Must be a power of 2.
|
||||||
|
|
||||||
private BufferHandle _inlineIndexBuffer;
|
private BufferHandle _inlineIndexBuffer;
|
||||||
private int _inlineIndexBufferSize;
|
private int _inlineIndexBufferSize;
|
||||||
private int _inlineIndexCount;
|
private int _inlineIndexCount;
|
||||||
|
private uint[] _buffer;
|
||||||
|
private int _bufferOffset;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Indicates if any index buffer data has been pushed.
|
/// Indicates if any index buffer data has been pushed.
|
||||||
@@ -38,9 +42,11 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
|||||||
/// Gets the number of elements on the current inline index buffer,
|
/// Gets the number of elements on the current inline index buffer,
|
||||||
/// while also reseting it to zero for the next draw.
|
/// while also reseting it to zero for the next draw.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
/// <param name="renderer">Host renderer</param>
|
||||||
/// <returns>Inline index bufffer count</returns>
|
/// <returns>Inline index bufffer count</returns>
|
||||||
public int GetAndResetInlineIndexCount()
|
public int GetAndResetInlineIndexCount(IRenderer renderer)
|
||||||
{
|
{
|
||||||
|
UpdateRemaining(renderer);
|
||||||
int temp = _inlineIndexCount;
|
int temp = _inlineIndexCount;
|
||||||
_inlineIndexCount = 0;
|
_inlineIndexCount = 0;
|
||||||
return temp;
|
return temp;
|
||||||
@@ -58,16 +64,12 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
|||||||
byte i2 = (byte)(argument >> 16);
|
byte i2 = (byte)(argument >> 16);
|
||||||
byte i3 = (byte)(argument >> 24);
|
byte i3 = (byte)(argument >> 24);
|
||||||
|
|
||||||
Span<uint> data = stackalloc uint[4];
|
int offset = _inlineIndexCount;
|
||||||
|
|
||||||
data[0] = i0;
|
PushData(renderer, offset, i0);
|
||||||
data[1] = i1;
|
PushData(renderer, offset + 1, i1);
|
||||||
data[2] = i2;
|
PushData(renderer, offset + 2, i2);
|
||||||
data[3] = i3;
|
PushData(renderer, offset + 3, i3);
|
||||||
|
|
||||||
int offset = _inlineIndexCount * 4;
|
|
||||||
|
|
||||||
renderer.SetBufferData(GetInlineIndexBuffer(renderer, offset), offset, MemoryMarshal.Cast<uint, byte>(data));
|
|
||||||
|
|
||||||
_inlineIndexCount += 4;
|
_inlineIndexCount += 4;
|
||||||
}
|
}
|
||||||
@@ -82,14 +84,10 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
|||||||
ushort i0 = (ushort)argument;
|
ushort i0 = (ushort)argument;
|
||||||
ushort i1 = (ushort)(argument >> 16);
|
ushort i1 = (ushort)(argument >> 16);
|
||||||
|
|
||||||
Span<uint> data = stackalloc uint[2];
|
int offset = _inlineIndexCount;
|
||||||
|
|
||||||
data[0] = i0;
|
PushData(renderer, offset, i0);
|
||||||
data[1] = i1;
|
PushData(renderer, offset + 1, i1);
|
||||||
|
|
||||||
int offset = _inlineIndexCount * 4;
|
|
||||||
|
|
||||||
renderer.SetBufferData(GetInlineIndexBuffer(renderer, offset), offset, MemoryMarshal.Cast<uint, byte>(data));
|
|
||||||
|
|
||||||
_inlineIndexCount += 2;
|
_inlineIndexCount += 2;
|
||||||
}
|
}
|
||||||
@@ -103,13 +101,61 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
|||||||
{
|
{
|
||||||
uint i0 = (uint)argument;
|
uint i0 = (uint)argument;
|
||||||
|
|
||||||
Span<uint> data = stackalloc uint[1];
|
int offset = _inlineIndexCount++;
|
||||||
|
|
||||||
data[0] = i0;
|
PushData(renderer, offset, i0);
|
||||||
|
}
|
||||||
|
|
||||||
int offset = _inlineIndexCount++ * 4;
|
/// <summary>
|
||||||
|
/// Pushes a 32-bit value to the index buffer.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="renderer">Host renderer</param>
|
||||||
|
/// <param name="offset">Offset where the data should be written, in 32-bit words</param>
|
||||||
|
/// <param name="value">Index value to be written</param>
|
||||||
|
private void PushData(IRenderer renderer, int offset, uint value)
|
||||||
|
{
|
||||||
|
if (_buffer == null)
|
||||||
|
{
|
||||||
|
_buffer = new uint[BufferCapacity];
|
||||||
|
}
|
||||||
|
|
||||||
renderer.SetBufferData(GetInlineIndexBuffer(renderer, offset), offset, MemoryMarshal.Cast<uint, byte>(data));
|
// We upload data in chunks.
|
||||||
|
// If we are at the start of a chunk, then the buffer might be full,
|
||||||
|
// in that case we need to submit any existing data before overwriting the buffer.
|
||||||
|
int subOffset = offset & (BufferCapacity - 1);
|
||||||
|
|
||||||
|
if (subOffset == 0 && offset != 0)
|
||||||
|
{
|
||||||
|
int baseOffset = (offset - BufferCapacity) * sizeof(uint);
|
||||||
|
BufferHandle buffer = GetInlineIndexBuffer(renderer, baseOffset, BufferCapacity * sizeof(uint));
|
||||||
|
renderer.SetBufferData(buffer, baseOffset, MemoryMarshal.Cast<uint, byte>(_buffer));
|
||||||
|
}
|
||||||
|
|
||||||
|
_buffer[subOffset] = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Makes sure that any pending data is submitted to the GPU before the index buffer is used.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="renderer">Host renderer</param>
|
||||||
|
private void UpdateRemaining(IRenderer renderer)
|
||||||
|
{
|
||||||
|
int offset = _inlineIndexCount;
|
||||||
|
if (offset == 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int count = offset & (BufferCapacity - 1);
|
||||||
|
if (count == 0)
|
||||||
|
{
|
||||||
|
count = BufferCapacity;
|
||||||
|
}
|
||||||
|
|
||||||
|
int baseOffset = (offset - count) * sizeof(uint);
|
||||||
|
int length = count * sizeof(uint);
|
||||||
|
BufferHandle buffer = GetInlineIndexBuffer(renderer, baseOffset, length);
|
||||||
|
renderer.SetBufferData(buffer, baseOffset, MemoryMarshal.Cast<uint, byte>(_buffer).Slice(0, length));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -117,12 +163,13 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="renderer">Host renderer</param>
|
/// <param name="renderer">Host renderer</param>
|
||||||
/// <param name="offset">Offset where the data will be written</param>
|
/// <param name="offset">Offset where the data will be written</param>
|
||||||
|
/// <param name="length">Number of bytes that will be written</param>
|
||||||
/// <returns>Buffer handle</returns>
|
/// <returns>Buffer handle</returns>
|
||||||
private BufferHandle GetInlineIndexBuffer(IRenderer renderer, int offset)
|
private BufferHandle GetInlineIndexBuffer(IRenderer renderer, int offset, int length)
|
||||||
{
|
{
|
||||||
// Calculate a reasonable size for the buffer that can fit all the data,
|
// Calculate a reasonable size for the buffer that can fit all the data,
|
||||||
// and that also won't require frequent resizes if we need to push more data.
|
// and that also won't require frequent resizes if we need to push more data.
|
||||||
int size = BitUtils.AlignUp(offset + 0x10, 0x200);
|
int size = BitUtils.AlignUp(offset + length + 0x10, 0x200);
|
||||||
|
|
||||||
if (_inlineIndexBuffer == BufferHandle.Null)
|
if (_inlineIndexBuffer == BufferHandle.Null)
|
||||||
{
|
{
|
||||||
|
@@ -130,6 +130,10 @@ namespace Ryujinx.Graphics.Gpu.Image
|
|||||||
return ref descriptor;
|
return ref descriptor;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
texture.SynchronizeMemory();
|
||||||
|
}
|
||||||
|
|
||||||
Items[id] = texture;
|
Items[id] = texture;
|
||||||
|
|
||||||
@@ -233,7 +237,7 @@ namespace Ryujinx.Graphics.Gpu.Image
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Queues a request to update a texture's mapping.
|
/// Queues a request to update a texture's mapping.
|
||||||
/// Mapping is updated later to avoid deleting the texture if it is still sparsely mapped.
|
/// Mapping is updated later to avoid deleting the texture if it is still sparsely mapped.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="texture">Texture with potential mapping change</param>
|
/// <param name="texture">Texture with potential mapping change</param>
|
||||||
|
@@ -14,6 +14,9 @@ namespace Ryujinx.HLE.HOS.Services.Nim
|
|||||||
// CreateServerInterface(pid, handle<unknown>, u64) -> object<nn::ec::IShopServiceAccessServer>
|
// CreateServerInterface(pid, handle<unknown>, u64) -> object<nn::ec::IShopServiceAccessServer>
|
||||||
public ResultCode CreateServerInterface(ServiceCtx context)
|
public ResultCode CreateServerInterface(ServiceCtx context)
|
||||||
{
|
{
|
||||||
|
// Close transfer memory immediately as we don't use it.
|
||||||
|
context.Device.System.KernelContext.Syscall.CloseHandle(context.Request.HandleDesc.ToCopy[0]);
|
||||||
|
|
||||||
MakeObject(context, new IShopServiceAccessServer());
|
MakeObject(context, new IShopServiceAccessServer());
|
||||||
|
|
||||||
Logger.Stub?.PrintStub(LogClass.ServiceNim);
|
Logger.Stub?.PrintStub(LogClass.ServiceNim);
|
||||||
|
Reference in New Issue
Block a user