Compare commits
19 commits
2f90198fb0
...
31f9ff3903
Author | SHA1 | Date | |
---|---|---|---|
|
31f9ff3903 | ||
|
6ce49a2dc7 | ||
|
ccd330ba0f | ||
|
fd40bd064e | ||
|
5421d9308d | ||
|
eb0e0fedce | ||
|
0f00bb1e5c | ||
|
d644d2ba5c | ||
|
4ce3f5b29d | ||
|
415315af6a | ||
|
f5d415dfef | ||
|
37a43b98db | ||
|
1e01c8b7c2 | ||
|
3884ffa628 | ||
|
9630691d13 | ||
|
8be123440d | ||
|
601c924699 | ||
|
4b40ffdb2d | ||
|
18231cc9da |
36 changed files with 483 additions and 28 deletions
|
@ -667,8 +667,36 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
|
|
||||||
if (PrepareOutputBuffer(cbs, hostSize, buffer, out VkBuffer copyToBuffer, out BufferHolder tempCopyHolder))
|
if (PrepareOutputBuffer(cbs, hostSize, buffer, out VkBuffer copyToBuffer, out BufferHolder tempCopyHolder))
|
||||||
{
|
{
|
||||||
|
// No barrier necessary, as this is a temporary copy buffer.
|
||||||
offset = 0;
|
offset = 0;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
BufferHolder.InsertBufferBarrier(
|
||||||
|
_gd,
|
||||||
|
cbs.CommandBuffer,
|
||||||
|
copyToBuffer,
|
||||||
|
BufferHolder.DefaultAccessFlags,
|
||||||
|
AccessFlags.TransferWriteBit,
|
||||||
|
PipelineStageFlags.AllCommandsBit,
|
||||||
|
PipelineStageFlags.TransferBit,
|
||||||
|
offset,
|
||||||
|
outSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
InsertImageBarrier(
|
||||||
|
_gd.Api,
|
||||||
|
cbs.CommandBuffer,
|
||||||
|
image,
|
||||||
|
TextureStorage.DefaultAccessMask,
|
||||||
|
AccessFlags.TransferReadBit,
|
||||||
|
PipelineStageFlags.AllCommandsBit,
|
||||||
|
PipelineStageFlags.TransferBit,
|
||||||
|
Info.Format.ConvertAspectFlags(),
|
||||||
|
FirstLayer + layer,
|
||||||
|
FirstLevel + level,
|
||||||
|
1,
|
||||||
|
1);
|
||||||
|
|
||||||
CopyFromOrToBuffer(cbs.CommandBuffer, copyToBuffer, image, hostSize, true, layer, level, 1, 1, singleSlice: true, offset, stride);
|
CopyFromOrToBuffer(cbs.CommandBuffer, copyToBuffer, image, hostSize, true, layer, level, 1, 1, singleSlice: true, offset, stride);
|
||||||
|
|
||||||
|
@ -677,6 +705,19 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
CopyDataToOutputBuffer(cbs, tempCopyHolder, autoBuffer, hostSize, range.Offset);
|
CopyDataToOutputBuffer(cbs, tempCopyHolder, autoBuffer, hostSize, range.Offset);
|
||||||
tempCopyHolder.Dispose();
|
tempCopyHolder.Dispose();
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
BufferHolder.InsertBufferBarrier(
|
||||||
|
_gd,
|
||||||
|
cbs.CommandBuffer,
|
||||||
|
copyToBuffer,
|
||||||
|
AccessFlags.TransferWriteBit,
|
||||||
|
BufferHolder.DefaultAccessFlags,
|
||||||
|
PipelineStageFlags.TransferBit,
|
||||||
|
PipelineStageFlags.AllCommandsBit,
|
||||||
|
offset,
|
||||||
|
outSize);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private ReadOnlySpan<byte> GetData(CommandBufferPool cbp, PersistentFlushBuffer flushBuffer)
|
private ReadOnlySpan<byte> GetData(CommandBufferPool cbp, PersistentFlushBuffer flushBuffer)
|
||||||
|
|
198
src/Ryujinx.Tests/Graphics/AstcDecoderTests.cs
Normal file
198
src/Ryujinx.Tests/Graphics/AstcDecoderTests.cs
Normal file
|
@ -0,0 +1,198 @@
|
||||||
|
using LibHac.FsSystem;
|
||||||
|
using Microsoft.FSharp.Core;
|
||||||
|
using Microsoft.VisualBasic;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using Ryujinx.Graphics.Gpu;
|
||||||
|
using Ryujinx.Graphics.Texture.Astc;
|
||||||
|
using Ryujinx.HLE.HOS.Services.SurfaceFlinger;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Ryujinx.Tests.Graphics
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* NOTES
|
||||||
|
*
|
||||||
|
* HOW I GENERATED INPUT DATA
|
||||||
|
* Step 1. Create ASTC-compressed image from sample data.
|
||||||
|
* *** NOTE This image isn't 2^x evenly sized, it's 768x512 - something that would break down into nice squares, for sure.
|
||||||
|
* `astcenc-sse2 -cl MoreRocks.png MoreRocks.l-4x4-100.astc 4x4 100`
|
||||||
|
*
|
||||||
|
* Step 2. Decompress the data we just created.
|
||||||
|
* `astcenc-sse2 -dl MoreRocks.l-4x4-100.astc MoreRocks.l-4x4-100.astc.png`
|
||||||
|
*
|
||||||
|
* Step 3.
|
||||||
|
* I used convertio to convert the PNG generated in step 2 to create MorRocks.l-4x4-100.astc.rgba
|
||||||
|
|
||||||
|
* WHAT WE DO IN THE TEST BELOW:
|
||||||
|
* 1. Read the sample image, ASTC-compressed reference, and decompressed reference that we generated above.
|
||||||
|
* 2. Run TryDecodeToRgba8P on our ASTC-compressed texture.
|
||||||
|
* 2a. Write the output of step 2 to the disk.
|
||||||
|
* 3. Assert that the data we decompressed in our method is the same data as the decompressed reference image.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class AstcDecoderTests
|
||||||
|
{
|
||||||
|
private string _workingDir;
|
||||||
|
private string _testDataDir;
|
||||||
|
|
||||||
|
[SetUp]
|
||||||
|
public void SetupFixture()
|
||||||
|
{
|
||||||
|
_workingDir = TestContext.CurrentContext.TestDirectory;
|
||||||
|
_testDataDir = Path.Join(_workingDir, "Graphics", "TestData");
|
||||||
|
GraphicsConfig.EnableTextureRecompression = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// public void
|
||||||
|
[TestCase(4, 4)]
|
||||||
|
[TestCase(5, 5)]
|
||||||
|
[TestCase(5, 4)]
|
||||||
|
[TestCase(6, 5)]
|
||||||
|
[TestCase(6, 6)]
|
||||||
|
[TestCase(8, 5)]
|
||||||
|
[TestCase(8, 6)]
|
||||||
|
[TestCase(8, 8)]
|
||||||
|
[TestCase(10, 5)]
|
||||||
|
[TestCase(10, 6)]
|
||||||
|
[TestCase(10, 8)]
|
||||||
|
[TestCase(10, 10)]
|
||||||
|
[TestCase(12, 10)]
|
||||||
|
[TestCase(12, 12)]
|
||||||
|
public void Paramterized_BlockSizes_Test(int blockWidth, int blockHeight)
|
||||||
|
{
|
||||||
|
TestContext.Out.WriteLine($"Testing Block Size {blockWidth}x{blockHeight}");
|
||||||
|
var (encodedRef, decodedRef) = GetTestDataTupleFromShortname("MoreRocks", blockWidth, blockHeight);
|
||||||
|
int astcHeaderLength = 16;
|
||||||
|
|
||||||
|
// skip the header. Decode method doesn't work without this and will return false.
|
||||||
|
var rawastc = encodedRef[astcHeaderLength..];
|
||||||
|
|
||||||
|
int texWidth = 256;
|
||||||
|
int texHeight = 256;
|
||||||
|
byte[] outputBuffer = Array.Empty<byte>();
|
||||||
|
|
||||||
|
int depth = 1;
|
||||||
|
int levels = 1;
|
||||||
|
int layers = 1;
|
||||||
|
|
||||||
|
bool succeeded = AstcDecoder.TryDecodeToRgba8P(rawastc, blockWidth, blockHeight, texWidth, texHeight, depth, levels, layers, out outputBuffer);
|
||||||
|
|
||||||
|
// The decode function said it was valid data and that it could parse it.
|
||||||
|
Assert.AreEqual(true, succeeded);
|
||||||
|
// Length is the same as the one we made w/ ARM's decoder. That's good.
|
||||||
|
Assert.AreEqual(decodedRef.Length, outputBuffer.Length);
|
||||||
|
|
||||||
|
var wordsRef = RgbaWord.FromBytes(decodedRef.ToArray());
|
||||||
|
var wordsOut = RgbaWord.FromBytes(outputBuffer);
|
||||||
|
var wordDifferences = wordsRef.Select((x, i) => new { index = i, diff = x.Diff(wordsOut[i]) }).ToArray();
|
||||||
|
|
||||||
|
// BUT compression is funny.
|
||||||
|
// Calculate the byte differences.
|
||||||
|
var byteDifferences = decodedRef.ToArray().Select((x, i) => new { index = i, delta = x - outputBuffer[i] }).ToList();
|
||||||
|
|
||||||
|
var matchCount = byteDifferences.Count(x => x.delta == 0);
|
||||||
|
var matchPercent = ((float)matchCount / outputBuffer.Length);
|
||||||
|
|
||||||
|
var wordUnchangedCount = wordDifferences.Count(x => x.diff.IsZero());
|
||||||
|
var wordUnchangedPercent = (float)wordUnchangedCount / wordDifferences.Length;
|
||||||
|
|
||||||
|
TestContext.Out.WriteLine($"Pixel-wise comparison: {wordUnchangedPercent * 100:F4} ({wordUnchangedCount}/{wordDifferences.Length})");
|
||||||
|
TestContext.Out.WriteLine($"Byte-wise comparison: {matchPercent * 100:F4} ({matchCount}/{byteDifferences.Count}) were same.");
|
||||||
|
|
||||||
|
for (var threshold = 1; threshold < 32; threshold++)
|
||||||
|
{
|
||||||
|
var tc = byteDifferences.Count(x => Math.Abs(x.delta) >= threshold);
|
||||||
|
var tcp = ((float)tc / byteDifferences.Count);
|
||||||
|
if (tc > 0)
|
||||||
|
TestContext.Out.WriteLine($"{tcp * 100:F4}% ({tc}/{byteDifferences.Count}) are different by at least {threshold}.");
|
||||||
|
}
|
||||||
|
|
||||||
|
Assert.IsTrue(byteDifferences.All(x => Math.Abs(x.delta) <= 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get test data from FS using short name naming convention.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="shortName"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
private (ReadOnlyMemory<byte>, ReadOnlyMemory<byte>) GetTestDataTupleFromShortname(string shortName, int blockWidth, int blockHeight)
|
||||||
|
{
|
||||||
|
var encodedRef = GetFileDataFromPath($"{shortName}.l-{blockWidth}x{blockHeight}-100.astc");
|
||||||
|
// var decodedRef = _getFileDataFromPath($"{shortName}.s4x4.astc.png");
|
||||||
|
var rgba8raw = GetFileDataFromPath($"{shortName}.l-{blockWidth}x{blockHeight}-100.astc.rgba");
|
||||||
|
|
||||||
|
return (encodedRef, rgba8raw);
|
||||||
|
}
|
||||||
|
|
||||||
|
private ReadOnlyMemory<byte> GetFileDataFromPath(string relativeFilePath)
|
||||||
|
{
|
||||||
|
var fullPath = Path.Join(_testDataDir, relativeFilePath);
|
||||||
|
return File.ReadAllBytes(fullPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
private class RgbaWord
|
||||||
|
{
|
||||||
|
public byte r;
|
||||||
|
public byte g;
|
||||||
|
public byte b;
|
||||||
|
public byte a;
|
||||||
|
|
||||||
|
public bool IsZero()
|
||||||
|
{
|
||||||
|
return r == 0 && g == 0 && b == 0 && a == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool SameAs(RgbaWord other)
|
||||||
|
{
|
||||||
|
return this.r == other.r && this.g == other.g && this.b == other.b && this.a == other.a;
|
||||||
|
}
|
||||||
|
|
||||||
|
public RgbaWord Diff(RgbaWord other)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
|
||||||
|
Returns 0 for a field if equal and absolute value of diff if not.
|
||||||
|
|
||||||
|
|
||||||
|
*/
|
||||||
|
return new RgbaWord()
|
||||||
|
{
|
||||||
|
r = (byte)Math.Abs(this.r - other.r),
|
||||||
|
g = (byte)Math.Abs(this.g - other.g),
|
||||||
|
b = (byte)Math.Abs(this.b - other.b),
|
||||||
|
a = (byte)Math.Abs(this.a - other.a)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Return an array of RGBA words given an array of bytes.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="rawBytes"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static RgbaWord[] FromBytes(byte[] rawBytes)
|
||||||
|
{
|
||||||
|
var result = new List<RgbaWord>();
|
||||||
|
// rawbytes has to be factor-of-4-sized.
|
||||||
|
for (var i = 0; i < rawBytes.Length; i += 4)
|
||||||
|
{
|
||||||
|
result.Add(new RgbaWord()
|
||||||
|
{
|
||||||
|
r = rawBytes[i],
|
||||||
|
g = rawBytes[i + 1],
|
||||||
|
b = rawBytes[i + 2],
|
||||||
|
a = rawBytes[i + 3]
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return result.ToArray();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
BIN
src/Ryujinx.Tests/Graphics/TestData/MoreRocks.l-10x10-100.astc
Normal file
BIN
src/Ryujinx.Tests/Graphics/TestData/MoreRocks.l-10x10-100.astc
Normal file
Binary file not shown.
File diff suppressed because one or more lines are too long
BIN
src/Ryujinx.Tests/Graphics/TestData/MoreRocks.l-10x5-100.astc
Normal file
BIN
src/Ryujinx.Tests/Graphics/TestData/MoreRocks.l-10x5-100.astc
Normal file
Binary file not shown.
File diff suppressed because one or more lines are too long
BIN
src/Ryujinx.Tests/Graphics/TestData/MoreRocks.l-10x6-100.astc
Normal file
BIN
src/Ryujinx.Tests/Graphics/TestData/MoreRocks.l-10x6-100.astc
Normal file
Binary file not shown.
File diff suppressed because one or more lines are too long
BIN
src/Ryujinx.Tests/Graphics/TestData/MoreRocks.l-10x8-100.astc
Normal file
BIN
src/Ryujinx.Tests/Graphics/TestData/MoreRocks.l-10x8-100.astc
Normal file
Binary file not shown.
File diff suppressed because one or more lines are too long
BIN
src/Ryujinx.Tests/Graphics/TestData/MoreRocks.l-12x10-100.astc
Normal file
BIN
src/Ryujinx.Tests/Graphics/TestData/MoreRocks.l-12x10-100.astc
Normal file
Binary file not shown.
File diff suppressed because one or more lines are too long
BIN
src/Ryujinx.Tests/Graphics/TestData/MoreRocks.l-12x12-100.astc
Normal file
BIN
src/Ryujinx.Tests/Graphics/TestData/MoreRocks.l-12x12-100.astc
Normal file
Binary file not shown.
File diff suppressed because one or more lines are too long
BIN
src/Ryujinx.Tests/Graphics/TestData/MoreRocks.l-4x4-100.astc
Normal file
BIN
src/Ryujinx.Tests/Graphics/TestData/MoreRocks.l-4x4-100.astc
Normal file
Binary file not shown.
BIN
src/Ryujinx.Tests/Graphics/TestData/MoreRocks.l-4x4-100.astc.png
Normal file
BIN
src/Ryujinx.Tests/Graphics/TestData/MoreRocks.l-4x4-100.astc.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 172 KiB |
File diff suppressed because one or more lines are too long
BIN
src/Ryujinx.Tests/Graphics/TestData/MoreRocks.l-5x4-100.astc
Normal file
BIN
src/Ryujinx.Tests/Graphics/TestData/MoreRocks.l-5x4-100.astc
Normal file
Binary file not shown.
File diff suppressed because one or more lines are too long
BIN
src/Ryujinx.Tests/Graphics/TestData/MoreRocks.l-5x5-100.astc
Normal file
BIN
src/Ryujinx.Tests/Graphics/TestData/MoreRocks.l-5x5-100.astc
Normal file
Binary file not shown.
Binary file not shown.
BIN
src/Ryujinx.Tests/Graphics/TestData/MoreRocks.l-6x5-100.astc
Normal file
BIN
src/Ryujinx.Tests/Graphics/TestData/MoreRocks.l-6x5-100.astc
Normal file
Binary file not shown.
File diff suppressed because one or more lines are too long
BIN
src/Ryujinx.Tests/Graphics/TestData/MoreRocks.l-6x6-100.astc
Normal file
BIN
src/Ryujinx.Tests/Graphics/TestData/MoreRocks.l-6x6-100.astc
Normal file
Binary file not shown.
File diff suppressed because one or more lines are too long
BIN
src/Ryujinx.Tests/Graphics/TestData/MoreRocks.l-8x5-100.astc
Normal file
BIN
src/Ryujinx.Tests/Graphics/TestData/MoreRocks.l-8x5-100.astc
Normal file
Binary file not shown.
Binary file not shown.
BIN
src/Ryujinx.Tests/Graphics/TestData/MoreRocks.l-8x6-100.astc
Normal file
BIN
src/Ryujinx.Tests/Graphics/TestData/MoreRocks.l-8x6-100.astc
Normal file
Binary file not shown.
Binary file not shown.
BIN
src/Ryujinx.Tests/Graphics/TestData/MoreRocks.l-8x8-100.astc
Normal file
BIN
src/Ryujinx.Tests/Graphics/TestData/MoreRocks.l-8x8-100.astc
Normal file
Binary file not shown.
File diff suppressed because one or more lines are too long
BIN
src/Ryujinx.Tests/Graphics/TestData/MoreRocks.png
Normal file
BIN
src/Ryujinx.Tests/Graphics/TestData/MoreRocks.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 140 KiB |
BIN
src/Ryujinx.Tests/Graphics/TestData/astcenc-sse2.exe
Normal file
BIN
src/Ryujinx.Tests/Graphics/TestData/astcenc-sse2.exe
Normal file
Binary file not shown.
|
@ -1,4 +1,4 @@
|
||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net8.0</TargetFramework>
|
<TargetFramework>net8.0</TargetFramework>
|
||||||
|
@ -33,6 +33,213 @@
|
||||||
<ProjectReference Include="..\ARMeilleure\ARMeilleure.csproj" />
|
<ProjectReference Include="..\ARMeilleure\ARMeilleure.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<None Update="Graphics\TestData\astcenc-sse2.exe">
|
||||||
|
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
|
<None Update="Graphics\TestData\diff.png">
|
||||||
|
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
|
<None Update="Graphics\TestData\kodim01.l4x4.astc">
|
||||||
|
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
|
<None Update="Graphics\TestData\kodim01.l4x4.astc.png">
|
||||||
|
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
|
<None Update="Graphics\TestData\kodim01.l4x4.astc.tga">
|
||||||
|
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
|
<None Update="Graphics\TestData\kodim01.png">
|
||||||
|
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
|
<None Update="Graphics\TestData\kodim01.png.output.png">
|
||||||
|
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
|
<None Update="Graphics\TestData\kodim01.rgba">
|
||||||
|
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
|
<None Update="Graphics\TestData\MoreRocks.l-10x10-100.astc">
|
||||||
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
|
<None Update="Graphics\TestData\MoreRocks.l-10x10-100.astc.png">
|
||||||
|
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
|
<None Update="Graphics\TestData\MoreRocks.l-10x10-100.astc.png.rgba">
|
||||||
|
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
|
<None Update="Graphics\TestData\MoreRocks.l-10x10-100.astc.rgba">
|
||||||
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
|
<None Update="Graphics\TestData\MoreRocks.l-10x5-100.astc">
|
||||||
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
|
<None Update="Graphics\TestData\MoreRocks.l-10x5-100.astc.png">
|
||||||
|
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
|
<None Update="Graphics\TestData\MoreRocks.l-10x5-100.astc.png.rgba">
|
||||||
|
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
|
<None Update="Graphics\TestData\MoreRocks.l-10x5-100.astc.rgba">
|
||||||
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
|
<None Update="Graphics\TestData\MoreRocks.l-10x6-100.astc">
|
||||||
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
|
<None Update="Graphics\TestData\MoreRocks.l-10x6-100.astc.png">
|
||||||
|
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
|
<None Update="Graphics\TestData\MoreRocks.l-10x6-100.astc.png.rgba">
|
||||||
|
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
|
<None Update="Graphics\TestData\MoreRocks.l-10x6-100.astc.rgba">
|
||||||
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
|
<None Update="Graphics\TestData\MoreRocks.l-10x8-100.astc">
|
||||||
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
|
<None Update="Graphics\TestData\MoreRocks.l-10x8-100.astc.png">
|
||||||
|
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
|
<None Update="Graphics\TestData\MoreRocks.l-10x8-100.astc.png.rgba">
|
||||||
|
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
|
<None Update="Graphics\TestData\MoreRocks.l-10x8-100.astc.rgba">
|
||||||
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
|
<None Update="Graphics\TestData\MoreRocks.l-12x10-100.astc">
|
||||||
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
|
<None Update="Graphics\TestData\MoreRocks.l-12x10-100.astc.png">
|
||||||
|
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
|
<None Update="Graphics\TestData\MoreRocks.l-12x10-100.astc.png.rgba">
|
||||||
|
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
|
<None Update="Graphics\TestData\MoreRocks.l-12x10-100.astc.rgba">
|
||||||
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
|
<None Update="Graphics\TestData\MoreRocks.l-12x12-100.astc">
|
||||||
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
|
<None Update="Graphics\TestData\MoreRocks.l-12x12-100.astc.png">
|
||||||
|
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
|
<None Update="Graphics\TestData\MoreRocks.l-12x12-100.astc.png.rgba">
|
||||||
|
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
|
<None Update="Graphics\TestData\MoreRocks.l-12x12-100.astc.rgba">
|
||||||
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
|
<None Update="Graphics\TestData\MoreRocks.l-4x4-100.astc">
|
||||||
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
|
<None Update="Graphics\TestData\MoreRocks.l-4x4-100.astc.png">
|
||||||
|
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
|
<None Update="Graphics\TestData\MoreRocks.l-4x4-100.astc.png.rgba">
|
||||||
|
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
|
<None Update="Graphics\TestData\MoreRocks.l-4x4-100.astc.rgba">
|
||||||
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
|
<None Update="Graphics\TestData\MoreRocks.l-5x4-100.astc">
|
||||||
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
|
<None Update="Graphics\TestData\MoreRocks.l-5x4-100.astc.rgba">
|
||||||
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
|
<None Update="Graphics\TestData\MoreRocks.l-5x5-100.astc">
|
||||||
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
|
<None Update="Graphics\TestData\MoreRocks.l-5x5-100.astc.png">
|
||||||
|
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
|
<None Update="Graphics\TestData\MoreRocks.l-5x5-100.astc.png.rgba">
|
||||||
|
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
|
<None Update="Graphics\TestData\MoreRocks.l-5x5-100.astc.rgba">
|
||||||
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
|
<None Update="Graphics\TestData\MoreRocks.l-6x5-100.astc">
|
||||||
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
|
<None Update="Graphics\TestData\MoreRocks.l-6x5-100.astc.png">
|
||||||
|
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
|
<None Update="Graphics\TestData\MoreRocks.l-6x5-100.astc.png.rgba">
|
||||||
|
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
|
<None Update="Graphics\TestData\MoreRocks.l-6x5-100.astc.rgba">
|
||||||
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
|
<None Update="Graphics\TestData\MoreRocks.l-6x6-100.astc">
|
||||||
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
|
<None Update="Graphics\TestData\MoreRocks.l-6x6-100.astc.png">
|
||||||
|
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
|
<None Update="Graphics\TestData\MoreRocks.l-6x6-100.astc.png.rgba">
|
||||||
|
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
|
<None Update="Graphics\TestData\MoreRocks.l-6x6-100.astc.rgba">
|
||||||
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
|
<None Update="Graphics\TestData\MoreRocks.l-8x5-100.astc">
|
||||||
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
|
<None Update="Graphics\TestData\MoreRocks.l-8x5-100.astc.png">
|
||||||
|
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
|
<None Update="Graphics\TestData\MoreRocks.l-8x5-100.astc.png.rgba">
|
||||||
|
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
|
<None Update="Graphics\TestData\MoreRocks.l-8x5-100.astc.rgba">
|
||||||
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
|
<None Update="Graphics\TestData\MoreRocks.l-8x6-100.astc">
|
||||||
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
|
<None Update="Graphics\TestData\MoreRocks.l-8x6-100.astc.png">
|
||||||
|
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
|
<None Update="Graphics\TestData\MoreRocks.l-8x6-100.astc.png.rgba">
|
||||||
|
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
|
<None Update="Graphics\TestData\MoreRocks.l-8x6-100.astc.rgba">
|
||||||
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
|
<None Update="Graphics\TestData\MoreRocks.l-8x8-100.astc">
|
||||||
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
|
<None Update="Graphics\TestData\MoreRocks.l-8x8-100.astc.png">
|
||||||
|
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
|
<None Update="Graphics\TestData\MoreRocks.l-8x8-100.astc.png.rgba">
|
||||||
|
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
|
<None Update="Graphics\TestData\MoreRocks.l-8x8-100.astc.rgba">
|
||||||
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
|
<None Update="Graphics\TestData\MoreRocks.png">
|
||||||
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
|
<None Update="Graphics\TestData\MoreRocks.s4x4.astc">
|
||||||
|
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
|
<None Update="Graphics\TestData\MoreRocks.s4x4.astc.png">
|
||||||
|
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
|
<None Update="Graphics\TestData\MoreRocks.s4x4.astc.png.rgba">
|
||||||
|
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
|
<None Update="Graphics\TestData\MoreRocks.s4x4.astc.rgba">
|
||||||
|
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
|
<None Update="Graphics\TestData\MoreRocks.s4x4.astc.tga">
|
||||||
|
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
<Target Name="CopyUnicorn" AfterTargets="Build">
|
<Target Name="CopyUnicorn" AfterTargets="Build">
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<UnicornLib Include="..\Ryujinx.Tests.Unicorn\libs\$(TargetOS)\*unicorn.*" />
|
<UnicornLib Include="..\Ryujinx.Tests.Unicorn\libs\$(TargetOS)\*unicorn.*" />
|
||||||
|
|
|
@ -1,21 +1,20 @@
|
||||||
using LibHac.Ns;
|
|
||||||
using Ryujinx.Ava.Common.Locale;
|
using Ryujinx.Ava.Common.Locale;
|
||||||
|
|
||||||
namespace Ryujinx.Ava.UI.Models
|
namespace Ryujinx.Ava.UI.Models
|
||||||
{
|
{
|
||||||
public class TitleUpdateModel
|
public class TitleUpdateModel
|
||||||
{
|
{
|
||||||
public ApplicationControlProperty Control { get; }
|
public uint Version { get; }
|
||||||
public string Path { get; }
|
public string Path { get; }
|
||||||
|
public string Label { get; }
|
||||||
|
|
||||||
public string Label => LocaleManager.Instance.UpdateAndGetDynamicValue(
|
public TitleUpdateModel(uint version, string displayVersion, string path)
|
||||||
System.IO.Path.GetExtension(Path)?.ToLower() == ".xci" ? LocaleKeys.TitleBundledUpdateVersionLabel : LocaleKeys.TitleUpdateVersionLabel,
|
|
||||||
Control.DisplayVersionString.ToString()
|
|
||||||
);
|
|
||||||
|
|
||||||
public TitleUpdateModel(ApplicationControlProperty control, string path)
|
|
||||||
{
|
{
|
||||||
Control = control;
|
Version = version;
|
||||||
|
Label = LocaleManager.Instance.UpdateAndGetDynamicValue(
|
||||||
|
System.IO.Path.GetExtension(path)?.ToLower() == ".xci" ? LocaleKeys.TitleBundledUpdateVersionLabel : LocaleKeys.TitleUpdateVersionLabel,
|
||||||
|
displayVersion
|
||||||
|
);
|
||||||
Path = path;
|
Path = path;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -131,26 +131,11 @@ namespace Ryujinx.Ava.UI.ViewModels
|
||||||
|
|
||||||
public void SortUpdates()
|
public void SortUpdates()
|
||||||
{
|
{
|
||||||
var list = TitleUpdates.ToList();
|
var sortedUpdates = TitleUpdates.OrderByDescending(update => update.Version);
|
||||||
|
|
||||||
list.Sort((first, second) =>
|
|
||||||
{
|
|
||||||
if (string.IsNullOrEmpty(first.Control.DisplayVersionString.ToString()))
|
|
||||||
{
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(second.Control.DisplayVersionString.ToString()))
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return Version.Parse(first.Control.DisplayVersionString.ToString()).CompareTo(Version.Parse(second.Control.DisplayVersionString.ToString())) * -1;
|
|
||||||
});
|
|
||||||
|
|
||||||
Views.Clear();
|
Views.Clear();
|
||||||
Views.Add(new BaseModel());
|
Views.Add(new BaseModel());
|
||||||
Views.AddRange(list);
|
Views.AddRange(sortedUpdates);
|
||||||
|
|
||||||
if (SelectedUpdate == null)
|
if (SelectedUpdate == null)
|
||||||
{
|
{
|
||||||
|
@ -204,7 +189,9 @@ namespace Ryujinx.Ava.UI.ViewModels
|
||||||
controlNca.OpenFileSystem(NcaSectionType.Data, IntegrityCheckLevel.None).OpenFile(ref nacpFile.Ref, "/control.nacp".ToU8Span(), OpenMode.Read).ThrowIfFailure();
|
controlNca.OpenFileSystem(NcaSectionType.Data, IntegrityCheckLevel.None).OpenFile(ref nacpFile.Ref, "/control.nacp".ToU8Span(), OpenMode.Read).ThrowIfFailure();
|
||||||
nacpFile.Get.Read(out _, 0, SpanHelpers.AsByteSpan(ref controlData), ReadOption.None).ThrowIfFailure();
|
nacpFile.Get.Read(out _, 0, SpanHelpers.AsByteSpan(ref controlData), ReadOption.None).ThrowIfFailure();
|
||||||
|
|
||||||
var update = new TitleUpdateModel(controlData, path);
|
var displayVersion = controlData.DisplayVersionString.ToString();
|
||||||
|
var update = new TitleUpdateModel(content.Version.Version, displayVersion, path);
|
||||||
|
|
||||||
TitleUpdates.Add(update);
|
TitleUpdates.Add(update);
|
||||||
|
|
||||||
if (selected)
|
if (selected)
|
||||||
|
|
Loading…
Add table
Reference in a new issue